//===========================================================================//
// File:    LabRatdoc.cpp                                                     
// Project: LabRat                                                 		 
// Contents: 				  
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// ??/??/96  JSE  Initial coding.                                             
//---------------------------------------------------------------------------//
// Copyright (C) 1996, Virtual World Entertainment, Inc.                     //
// All Rights reserved worldwide                                             //
// This unpublished sourcecode is PROPRIETARY and CONFIDENTIAL               //
//===========================================================================//


#include "stdafx.h"
#include "LabRatDoc.h"


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

Logical BigEndian = True;;

void BigEndianConvert(LONG &value)
{
	ASSERT(sizeof(value) == 4);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[4];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[3];
		target[1] = array_of_bytes[2];
		target[2] = array_of_bytes[1];
		target[3] = array_of_bytes[0];

		LONG return_value = SKIPPY_CAST(LONG, target);

		value = return_value;
	}
}

void BigEndianConvert(DWORD &value)
{
	ASSERT(sizeof(value) == 4);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[4];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[3];
		target[1] = array_of_bytes[2];
		target[2] = array_of_bytes[1];
		target[3] = array_of_bytes[0];

		DWORD return_value = SKIPPY_CAST(DWORD, target);

		value = return_value;
	}
}


void BigEndianConvert(WORD &value)
{
	ASSERT(sizeof(value) == 2);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[2];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[1];
		target[1] = array_of_bytes[0];

		WORD return_value = SKIPPY_CAST(WORD, target);
	
		value = return_value;
	}
}

void BigEndianConvert(int &value)
{
	ASSERT(sizeof(value) == 4);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[4];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[3];
		target[1] = array_of_bytes[2];
		target[2] = array_of_bytes[1];
		target[3] = array_of_bytes[0];


		DWORD return_value = SKIPPY_CAST(int, target);

		value = return_value;
	}
}

void BigEndianConvert(float &value)
{
	ASSERT(sizeof(value) == 4);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[4];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[3];
		target[1] = array_of_bytes[2];
		target[2] = array_of_bytes[1];
		target[3] = array_of_bytes[0];

		float return_value = SKIPPY_CAST(float, target);

		value = return_value;
	}
}

void BigEndianConvert(double &value)
{
	ASSERT(sizeof(value) == 8);
	if (BigEndian == True)
	{
		BYTE *array_of_bytes;
		BYTE target[8];

		array_of_bytes = (BYTE *)&value;

		target[0] = array_of_bytes[7];
		target[1] = array_of_bytes[6];
		target[2] = array_of_bytes[5];
		target[3] = array_of_bytes[4];
		target[4] = array_of_bytes[3];
		target[5] = array_of_bytes[2];
		target[6] = array_of_bytes[1];
		target[7] = array_of_bytes[0];

		double return_value = SKIPPY_CAST(double, target);
	
		value = return_value;
	}
}


void BigEndianConvert(BYTE &value)
{
	// KILL THE WARNING!!!
	ASSERT(value == value);
}

/////////////////////////////////////////////////////////////////////////////
// CLabRatDoc

IMPLEMENT_DYNCREATE(CLabRatDoc, CDocument)

BEGIN_MESSAGE_MAP(CLabRatDoc, CDocument)
	//{{AFX_MSG_MAP(CLabRatDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CObarrayHolder

CObarrayHolder::CObarrayHolder()
{
	data = NULL;
	traceType = -1;
	traceEntryCount = -1;
	
}

CObarrayHolder::~CObarrayHolder()
{

	if (data != NULL)
	{
		if(!VirtualFree(data, size, MEM_DECOMMIT))
		{
		//	afxDump << "VirtualFree FAIL!!!!" << endl;
		}
		if(!VirtualFree(data, 0, MEM_RELEASE))
		{
		//	afxDump << "VirtualFree FAIL!!!!" << endl;
		}
	}

}


/////////////////////////////////////////////////////////////////////////////
// CLabRatDoc construction/destruction

CLabRatDoc::CLabRatDoc()
{
	// TODO: add one-time construction code here
	dataArray = NULL;
	classIDList = NULL;
	failedOpen = False;

	BigEndian = False;
	traceCount=0;
}

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

CLabRatDoc::~CLabRatDoc()
{

}

BOOL CLabRatDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CLabRatDoc serialization

void CLabRatDoc::Serialize(CArchive& ar)
{
//	afxDump << "CLabRatDoc::Serialize" << endl;


	if (ar.IsStoring())
		ar.SetStoreParams();  // use large defaults
	else
		ar.SetLoadParams(10240);


	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		CLoadingLogDlg loadingDlg;
		loadingDlg.DoModal(ar, this);
	}
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

void CLabRatDoc::LoadResource(CArchive& ar, CLoadingLogDlg *dialog_box)
{
	

	LONG Section;

	CFile *sample_file = ar.GetFile();
	
	ar.Flush();
	sample_file->Seek(0, CFile::begin);

	ar >> Section;

	BigEndian = False;

	if (Section == (int)'ONVR')
	{
	
		LONG size;
		ar >> size;

		LONG version;
		ar >> version;

		if (version == 0)
		{
			LoadOldResource(ar, dialog_box, 12);
			return;
		}
		else if (version == 1)
		{
			LoadOnePointZeroResourceBackward(ar, dialog_box);
			return;
		}
		else if (version == 2)
		{
			LoadTwoPointZeroResourceBackward(ar, dialog_box);
			return;
		}
		
		BigEndian = True;
		BigEndianConvert(size);
		BigEndianConvert(version);
		if (version == 2)
		{
		
			LoadTwoPointZeroResourceBackward(ar, dialog_box);
			return;
		}

		
	}
	else if (Section == (int)'RVNO')
	{
		LONG size;
		ar >> size;

		LONG version;
		ar >> version;

		if (version == 0)
		{
			LoadOldResource(ar, dialog_box, 12);
			return;
		}
		else if (version == 1)
		{
			LoadOnePointZeroResource(ar, dialog_box);
			return;
		}
		else if (version == 2)
		{
			LoadTwoPointZeroResource(ar, dialog_box);
			return;
		}
	}

	dialog_box->KillTimer(1);
	dialog_box->CancelRecived();

	failedOpen = True;

	AfxThrowArchiveException(CArchiveException::badIndex);
		
	return;


}



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

void 
	CLabRatDoc::LoadOnePointZeroResource(CArchive& ar, CLoadingLogDlg *dialog_box)
{

	LONG section;
	LONG size;

	DWORD current_pos = 12;

	LONG header_pos = -1;
	LONG log_pos = -1;
	LONG mesg_pos = -1;
	
	CFile *sample_file = ar.GetFile();


	LONG message_size;

	DWORD total_size = sample_file->GetLength();

	dialog_box->AddString("LOADING RESOURCE FORMAT 1.0");

	while (current_pos < total_size)
	{
		ar >> section;
		ar >> size;
		current_pos += 8;

		if (section == (int)'HDRS')
		{
			header_pos = current_pos; 	
		}
		else if (section == (int)'LOGS')
		{
			log_pos = current_pos;	
			sampleSize = size;
			dialog_box->SetMaxCount(sampleSize * 2);
		}
		else if (section == (int)'MSGS')
		{
			mesg_pos = current_pos;
			message_size = size;
		}
		current_pos += size;
		ar.Flush();
		sample_file->Seek(current_pos, CFile::begin);
	}


	if (header_pos == -1)
	{
		dialog_box->KillTimer(1);
		dialog_box->CancelRecived();
		failedOpen = True;
		AfxThrowArchiveException(CArchiveException::badIndex);
		
		return;
	}

	LoadHeader(ar, header_pos, dialog_box);

	if (log_pos != -1)
	{
		LoadTracesOne(ar, log_pos, dialog_box);
	}

	LoadMessages(ar, mesg_pos, dialog_box, message_size);

}


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

void 
	CLabRatDoc::LoadTwoPointZeroResource(CArchive& ar, CLoadingLogDlg *dialog_box)
{

	LONG section;
	LONG size;

	DWORD current_pos = 12;

	LONG header_pos = -1;
	LONG log_pos = -1;
	LONG mesg_pos = -1;
	
	CFile *sample_file = ar.GetFile();


	LONG message_size;

	DWORD total_size = sample_file->GetLength();

	dialog_box->AddString("LOADING RESOURCE FORMAT 2.0");

	while (current_pos < total_size)
	{
		ar >> section;
		ar >> size;
		current_pos += 8;

		if (section == (int)'HDRS')
		{
			header_pos = current_pos; 	
		}
		else if (section == (int)'LOGS')
		{
			log_pos = current_pos;	
			sampleSize = size;
			dialog_box->SetMaxCount(sampleSize * 2);
		}
		else if (section == (int)'MSGS')
		{
			mesg_pos = current_pos;
			message_size = size;
		}
		current_pos += size;
		ar.Flush();
		sample_file->Seek(current_pos, CFile::begin);
	}


	if (header_pos == -1)
	{
		dialog_box->KillTimer(1);
		dialog_box->CancelRecived();
		failedOpen = True;
		AfxThrowArchiveException(CArchiveException::badIndex);
		
		return;
	}

	LoadHeader(ar, header_pos, dialog_box);

	if (log_pos != -1)
	{
		LoadTracesTwo(ar, log_pos, dialog_box);
	}


	if (mesg_pos != -1)
	{
		LoadMessages(ar, mesg_pos, dialog_box, message_size);
	}
}


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

void 
	CLabRatDoc::LoadOnePointZeroResourceBackward(CArchive& ar, CLoadingLogDlg *dialog_box)
{

	LONG section;
	LONG size;

	DWORD current_pos = 12;

	LONG header_pos = -1;
	LONG log_pos = -1;
	LONG mesg_pos = -1;
	
	CFile *sample_file = ar.GetFile();


	LONG message_size;

	DWORD total_size = sample_file->GetLength();

	dialog_box->AddString("LOADING RESOURCE FORMAT 1.0");

	while (current_pos < total_size)
	{
		ar >> section;
		ar >> size;
		current_pos += 8;

		if (section == (int)'SRDH')
		{
			header_pos = current_pos; 	
		}
		else if (section == (int)'SGOL')
		{
			log_pos = current_pos;	
			sampleSize = size;
			dialog_box->SetMaxCount(sampleSize * 2);
		}
		else if (section == (int)'SGSM')
		{
			mesg_pos = current_pos;
			message_size = size;
		}
		current_pos += size;
		ar.Flush();
		sample_file->Seek(current_pos, CFile::begin);
	}


	if (header_pos == -1)
	{
		dialog_box->KillTimer(1);
		dialog_box->CancelRecived();
		failedOpen = True;
		AfxThrowArchiveException(CArchiveException::badIndex);
		
		return;
	}

	LoadHeader(ar, header_pos, dialog_box);

	if (log_pos != -1)
	{
		LoadTracesOne(ar, log_pos, dialog_box);
	}

	LoadMessages(ar, mesg_pos, dialog_box, message_size);

}


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

void 
	CLabRatDoc::LoadTwoPointZeroResourceBackward(CArchive& ar, CLoadingLogDlg *dialog_box)
{



	LONG section;
	LONG size;

	DWORD current_pos = 12;

	LONG header_pos = -1;
	LONG log_pos = -1;
	LONG mesg_pos = -1;
	
	CFile *sample_file = ar.GetFile();


	LONG message_size;

	DWORD total_size = sample_file->GetLength();

	dialog_box->AddString("LOADING RESOURCE FORMAT 2.0");

	dialog_box->AddString("BACKWARD");

	if (BigEndian)
	{
		dialog_box->AddString("8 BYTE BIG ENDIAN!!!!");
	}

	while (current_pos < total_size)
	{
		ar >> section;
		ar >> size;

		
		BigEndianConvert(size);

		current_pos += 8;

		if (section == (int)'SRDH')
		{
			header_pos = current_pos; 	
		}
		else if (section == (int)'SGOL')
		{
			log_pos = current_pos;	
			sampleSize = size;
			dialog_box->SetMaxCount(sampleSize * 2);
		}
		else if (section == (int)'SGSM')
		{
			mesg_pos = current_pos;
			message_size = size;
		}
		current_pos += size;
		ar.Flush();
		sample_file->Seek(current_pos, CFile::begin);
	}


	if (header_pos == -1)
	{
		dialog_box->KillTimer(1);
		dialog_box->CancelRecived();
		failedOpen = True;
		AfxThrowArchiveException(CArchiveException::badIndex);
		
		return;
	}

	LoadHeader(ar, header_pos, dialog_box);

	if (log_pos != -1)
	{
		if (BigEndian == False)
		{
			LoadTracesTwo(ar, log_pos, dialog_box);
		}
		else
		{
			LoadTracesTwo8Byte(ar, log_pos, dialog_box);
		}
	}

	LoadMessages(ar, mesg_pos, dialog_box, message_size);

}


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


void 
	CLabRatDoc::LoadMessages(CArchive& ar, LONG position, CLoadingLogDlg *dialog_box, LONG message_size)
{


	CFile *sample_file = ar.GetFile();
	ar.Flush();
	sample_file->Seek(position, CFile::begin);

	dialog_box->AddString("PROCESSING CLASSID::MESSAGEID LIST");

	LONG bytes_read = 0;
	
	LONG class_id;
	LONG message_count;


	char name[250];


	classIDList = new CObList(100);

	while (bytes_read < message_size)
	{
		
		ar >> class_id;
		ar >> message_count;

		BigEndianConvert(class_id);
		BigEndianConvert(message_count);


		bytes_read += 8;


		ClassIDList *classID = new ClassIDList;

		classID->classID = class_id;
		classID->messageCount = message_count + 1;

		classID->messageList = new CObArray;

		classID->messageList->SetSize(classID->messageCount);

		int i = 0;
		BYTE character = 1;
		while (character != '\0')
		{
			ar >> character;
			name[i] = character;
			bytes_read += 1;
			++i;
		}

		classID->entityName = name;


		classID->messageList->SetAt( 0, (CObject *) new CObjString( "NULLID" ) );

		for (int count = 0; count < message_count; ++count)
		{

			i = 0;
			character = 1;
			while (character != '\0')
			{
				ar >> character;
				name[i] = character;
				++bytes_read;
				++i;
			}

			CObject *obj = (CObject *)new CObjString(name);

			classID->messageList->SetAt(count + 1, obj);
			//BREAKABLE_LINE;
		}

		

		ar.Flush();
		DWORD align = sample_file->GetPosition();
		BYTE throw_away;
		while ((align%4) != 0)
		{
			ar >> throw_away;
			++align;
			++bytes_read;
		}


		classIDList->AddTail(classID);

	}



}
	
/////////////////////////////////////////////////////////////////////////////

void 
	CLabRatDoc::LoadHeader(CArchive& ar, LONG position, CLoadingLogDlg *dialog_box)
{


	CFile *sample_file = ar.GetFile();
	ar.Flush();
	sample_file->Seek(position, CFile::begin);

	dialog_box->AddString("PROCESSING HEADER INFO");

	LONG trace_count;

	ar >> trace_count;
	BigEndianConvert(trace_count);

	++trace_count;
	
	traceCount = trace_count;


	char number_buffer[10];
	char temp[200];

	ltoa( traceCount, number_buffer, 10);
	strcpy(temp, "trace count : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);


	dataArray = new CObArray;
	dataArray->SetSize(trace_count);

	CObarrayHolder *trace;

	BYTE bLetter; 
	char cLetter;
	LONG trace_type;
	LONG length;
   
	
	for ( int i = 0; i < traceCount; ++i)
	{
		trace = new CObarrayHolder;
		dataArray->SetAt(i, trace);
		   
		if ( i != (traceCount - 1))
		{
			ar >> length;
			ar >> trace_type;
			BigEndianConvert(length);
			BigEndianConvert(trace_type);

			trace->traceType = trace_type;
			
			trace->name = "";
			ar >> bLetter;
			

			while(bLetter != NULL)
			{
				cLetter = bLetter;
				trace->name += cLetter;
				ar >> bLetter;
			}
		
			trace->traceEntryCount = 0;
		
			
			ar.Flush();
			DWORD align = sample_file->GetPosition();
			BYTE throw_away;
			while ((align%4) != 0)
			{
				ar >> throw_away;
				++align;
			}

		}
		else
		{
			trace->traceType = MarkerTraceType;
			trace->name = "Marker";
			trace->traceEntryCount = 0;
		}
	}
}

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


void 
	CLabRatDoc::LoadTracesOne(CArchive& ar, LONG position, CLoadingLogDlg *dialog_box)
{


	dialog_box->AddString("PROCESSING LOGS");

	CFile *sample_file = ar.GetFile();
	
	CObarrayHolder *data_holder;
	LONG length;
	BYTE trace_number;
	BYTE  edge_flag;

	WORD  edge_tick;
	float edge_fraction;
	LONG  total_bytes_read = 0;


	DWORD next_entry = position;

	dialog_box->count = 0;
	
	MSG message;
	int message_count = 0;

	BOOL first_pass = TRUE;

	while ( total_bytes_read < sampleSize )
	{
		
		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			for (int i = 0; i < traceCount; ++i)
			{
				data_holder = (CObarrayHolder*)dataArray->GetAt(i);
				data_holder->traceEntryCount = 0;
			}

			stillLoading = FALSE;
			//dialog_box->CancelRecived();
			
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}



		ar.Flush();
		next_entry = sample_file->GetPosition();

		
		ar >> length;
		BigEndianConvert(length);

		int advance = length;
		next_entry += length;

		
		ar >> edge_fraction;
		ar >> edge_tick;
		
		
		ar >> trace_number;
		ar >> edge_flag;
		
		BigEndianConvert(edge_fraction);
		BigEndianConvert(edge_tick);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);

		if (first_pass == TRUE)
		{
			first_pass = FALSE;
			firstTrace = SECONDS(edge_tick, edge_fraction);
			lastTrace = SECONDS(edge_tick, edge_fraction);
		}
		if (SECONDS(edge_tick, edge_fraction) < firstTrace)
		{
			firstTrace = SECONDS(edge_tick, edge_fraction);
		}
		if (SECONDS(edge_tick, edge_fraction) > lastTrace)
		{
			lastTrace = SECONDS(edge_tick, edge_fraction);
		}


		if (edge_flag == MarkerFlag)
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(traceCount - 1);
			data_holder->traceEntryCount += 1;

		}
		else
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(trace_number);
			data_holder->traceEntryCount += 1;
		}



		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;

		total_bytes_read += advance;
		dialog_box->count = total_bytes_read;

		
	}

	int total_size = 0;


	char number_buffer[20];


	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("ALLOCATING MEMORY");
	dialog_box->AddString("");

	char temp[100];

	dialog_box->AddString("Trace List:");

	for (int i = 0; i < traceCount; ++i)
	{
		data_holder = (CObarrayHolder*)dataArray->GetAt(i);

		TraceStorage::AllocateStorage(data_holder);

		strcpy(temp, data_holder->name);
		strcat(temp, " - elements: ");
		ltoa( data_holder->traceEntryCount,number_buffer, 10); 
		strcat(temp, number_buffer);
		strcat(temp, " bytes : ");
		ltoa(data_holder->size, number_buffer, 10);
		strcat(temp, number_buffer);

		dialog_box->AddString(temp);
		

		data_holder->traceEntryCount = 0;
		total_size += data_holder->size;
	}

	dialog_box->AddString("");
	dialog_box->AddString("");

	ltoa(total_size, number_buffer, 10);
	dialog_box->AddString("TOTAL MEMORY ALLOCATED: ");
	dialog_box->AddString(number_buffer);
	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("COPYING DATA INTO MEMORY");

	
	next_entry = position;
	
	message_count = 0;
	total_bytes_read = 0;

	while ( total_bytes_read < sampleSize )
	{
		

		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			stillLoading = FALSE;
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}


		ar.Flush();
		next_entry = sample_file->GetPosition();

		ar >> length;
		BigEndianConvert(length);

		int advance = length;
		next_entry += length;


		ar >> edge_fraction;
		ar >> edge_tick;
		ar >> trace_number;
		ar >> edge_flag;

		BigEndianConvert(edge_fraction);
		BigEndianConvert(edge_tick);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);
				
		if (edge_flag == MarkerFlag)
		{
			trace_number = (unsigned char)(traceCount - 1);
		}


		data_holder = (CObarrayHolder*)dataArray->GetAt(trace_number);


	
		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(SECONDS(edge_tick, edge_fraction) - firstTrace);


		if (data_holder->traceEntryCount > 0)
		{
			if(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->GetTraceTime() <
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount-1)->GetTraceTime())
			{
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(SECONDS(edge_tick + 1, edge_fraction) - firstTrace);
			}
		}
	

		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->LoadData(ar, data_holder, edge_flag); 


		data_holder->traceEntryCount += 1;


		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;


		total_bytes_read += advance;
		dialog_box->count = total_bytes_read + sampleSize;
	}

	lastTrace -= firstTrace;
	firstTrace = 0.0f;

	stillLoading = FALSE;

}


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


void 
	CLabRatDoc::LoadTracesTwo(CArchive& ar, LONG position, CLoadingLogDlg *dialog_box)
{


	dialog_box->AddString("PROCESSING LOGS");

	CFile *sample_file = ar.GetFile();
	
	CObarrayHolder *data_holder;
	LONG length;
	BYTE trace_number;
	BYTE  edge_flag;
	BYTE throwaway;
	
	double trace_time;
	LONG  total_bytes_read = 0;


	DWORD next_entry = position;

	dialog_box->count = 0;
	
	MSG message;
	int message_count = 0;

	BOOL first_pass = TRUE;

	while ( total_bytes_read < sampleSize )
	{
		
		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			for (int i = 0; i < traceCount; ++i)
			{
				data_holder = (CObarrayHolder*)dataArray->GetAt(i);
				data_holder->traceEntryCount = 0;
			}

			stillLoading = FALSE;
			//dialog_box->CancelRecived();
			
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}



		ar.Flush();
		next_entry = sample_file->GetPosition();

		
		ar >> length;

		BigEndianConvert(length);
		

		int advance = length;
		next_entry += length;

		
		ar >> trace_time;
		ar >> trace_number;
		ar >> edge_flag;
		
		BigEndianConvert(trace_time);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);

		if (first_pass == TRUE)
		{
			first_pass = FALSE;
			firstTrace = trace_time;
			lastTrace = trace_time;
		}
		if (trace_time < firstTrace)
		{
			firstTrace = trace_time;
		}
		if (trace_time > lastTrace)
		{
			lastTrace = trace_time;
		}


		if (edge_flag == MarkerFlag)
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(traceCount - 1);
			data_holder->traceEntryCount += 1;

		}
		else
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(trace_number);
			data_holder->traceEntryCount += 1;
		}



		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;

		total_bytes_read += advance;
		dialog_box->count = total_bytes_read;

		
	}

	int total_size = 0;


	char number_buffer[20];


	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("ALLOCATING MEMORY");
	dialog_box->AddString("");

	char temp[100];

	dialog_box->AddString("Trace List:");

	for (int i = 0; i < traceCount; ++i)
	{
		data_holder = (CObarrayHolder*)dataArray->GetAt(i);

		TraceStorage::AllocateStorage(data_holder);

		strcpy(temp, data_holder->name);
		strcat(temp, " - elements: ");
		ltoa( data_holder->traceEntryCount,number_buffer, 10); 
		strcat(temp, number_buffer);
		strcat(temp, " bytes : ");
		ltoa(data_holder->size, number_buffer, 10);
		strcat(temp, number_buffer);

		dialog_box->AddString(temp);
		

		data_holder->traceEntryCount = 0;
		total_size += data_holder->size;
	}

	dialog_box->AddString("");
	dialog_box->AddString("");

	ltoa(total_size, number_buffer, 10);
	dialog_box->AddString("TOTAL MEMORY ALLOCATED: ");
	dialog_box->AddString(number_buffer);
	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("COPYING DATA INTO MEMORY");

	
	next_entry = position;
	
	message_count = 0;
	total_bytes_read = 0;

	while ( total_bytes_read < sampleSize )
	{
		

		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			stillLoading = FALSE;
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}


		ar.Flush();
		next_entry = sample_file->GetPosition();

		ar >> length;

		BigEndianConvert(length);

		int advance = length;
		next_entry += length;


		ar >> trace_time;
	
		ar >> trace_number;
		ar >> edge_flag;
		ar >> throwaway;
		ar >> throwaway;

		BigEndianConvert(trace_time);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);
				
		if (edge_flag == MarkerFlag)
		{
			trace_number = (unsigned char)(traceCount - 1);
		}


		data_holder = (CObarrayHolder*)dataArray->GetAt(trace_number);


	
		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(trace_time - firstTrace);


		if (data_holder->traceEntryCount > 0)
		{
			if(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->GetTraceTime() <
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount-1)->GetTraceTime())
			{
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount-1)->GetTraceTime());
			}
		}
	

		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->LoadData(ar, data_holder, edge_flag); 


		data_holder->traceEntryCount += 1;


		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;


		total_bytes_read += advance;
		dialog_box->count = total_bytes_read + sampleSize;
	}

	lastTrace -= firstTrace;
	firstTrace = 0.0f;

	stillLoading = FALSE;

}

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


void 
	CLabRatDoc::LoadTracesTwo8Byte(CArchive& ar, LONG position, CLoadingLogDlg *dialog_box)
{

	double one = 1.0;


	dialog_box->AddString("PROCESSING LOGS");

	CFile *sample_file = ar.GetFile();
	
	CObarrayHolder *data_holder;
	LONG length;
	BYTE trace_number;
	BYTE  edge_flag;
	BYTE throwaway;
	
	double trace_time;
	LONG  total_bytes_read = 0;


	DWORD next_entry = position;

	dialog_box->count = 0;
	
	MSG message;
	int message_count = 0;

	BOOL first_pass = TRUE;

	while ( total_bytes_read < sampleSize )
	{
		
		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			for (int i = 0; i < traceCount; ++i)
			{
				data_holder = (CObarrayHolder*)dataArray->GetAt(i);
				data_holder->traceEntryCount = 0;
			}

			stillLoading = FALSE;
			//dialog_box->CancelRecived();
			
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}



		ar.Flush();
		next_entry = sample_file->GetPosition();

		
		ar >> length;

		BigEndianConvert(length);
		
		// 8 BYTE ALIGHN
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;

		int advance = length;
		next_entry += length;
		
		ar >> trace_time;
		ar >> trace_number;
		ar >> edge_flag;

		// 8 byte align
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;


		BigEndianConvert(trace_time);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);

		if (first_pass == TRUE)
		{
			first_pass = FALSE;
			firstTrace = trace_time;
			lastTrace = trace_time;
		}
		if (trace_time < firstTrace)
		{
			firstTrace = trace_time;
		}
		if (trace_time > lastTrace)
		{
			lastTrace = trace_time;
		}


		if (edge_flag == MarkerFlag)
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(traceCount - 1);
			data_holder->traceEntryCount += 1;

		}
		else
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(trace_number);
			data_holder->traceEntryCount += 1;
		}



		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;

		total_bytes_read += advance;
		dialog_box->count = total_bytes_read;

		
	}

	int total_size = 0;


	char number_buffer[20];


	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("ALLOCATING MEMORY");
	dialog_box->AddString("");

	char temp[100];

	dialog_box->AddString("Trace List:");

	for (int i = 0; i < traceCount; ++i)
	{
		data_holder = (CObarrayHolder*)dataArray->GetAt(i);

		TraceStorage::AllocateStorage(data_holder);

		strcpy(temp, data_holder->name);
		strcat(temp, " - elements: ");
		ltoa( data_holder->traceEntryCount,number_buffer, 10); 
		strcat(temp, number_buffer);
		strcat(temp, " bytes : ");
		ltoa(data_holder->size, number_buffer, 10);
		strcat(temp, number_buffer);

		dialog_box->AddString(temp);
		

		data_holder->traceEntryCount = 0;
		total_size += data_holder->size;
	}

	dialog_box->AddString("");
	dialog_box->AddString("");

	ltoa(total_size, number_buffer, 10);
	dialog_box->AddString("TOTAL MEMORY ALLOCATED: ");
	dialog_box->AddString(number_buffer);
	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("COPYING DATA INTO MEMORY");

	
	next_entry = position;
	
	message_count = 0;
	total_bytes_read = 0;

	while ( total_bytes_read < sampleSize )
	{
		

		ar.Flush();
		sample_file->Seek(next_entry, CFile::begin);

		if (dialog_box->stopProcess == TRUE)
		{
			stillLoading = FALSE;
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}


		ar.Flush();
		next_entry = sample_file->GetPosition();

		ar >> length;

		// 8 BYTE ALIGHN
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;


		BigEndianConvert(length);

		int advance = length;
		next_entry += length;


		ar >> trace_time;
	
		ar >> trace_number;
		ar >> edge_flag;

		// 8 byte align
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;
		ar >> throwaway;

		BigEndianConvert(trace_time);
		BigEndianConvert(trace_number);
		BigEndianConvert(edge_flag);
				
		if (edge_flag == MarkerFlag)
		{
			trace_number = (unsigned char)(traceCount - 1);
		}


		data_holder = (CObarrayHolder*)dataArray->GetAt(trace_number);


	
		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(trace_time - firstTrace);


		if (data_holder->traceEntryCount > 0)
		{
			if(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->GetTraceTime() <
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount-1)->GetTraceTime())
			{
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount-1)->GetTraceTime());
			}
		}
	

		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->LoadData(ar, data_holder, edge_flag); 


		data_holder->traceEntryCount += 1;


		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;


		total_bytes_read += advance;
		dialog_box->count = total_bytes_read + sampleSize;
	}

	lastTrace -= firstTrace;
	firstTrace = 0.0f;

	stillLoading = FALSE;

}

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

void 
	CLabRatDoc::LoadOldResource(CArchive& ar, CLoadingLogDlg *dialog_box, int file_start)
{

	stillLoading = TRUE;

	LONG sample_size;
	LONG sample_start;
	BYTE trace_count;

	sample_start = 1 + file_start;
	sample_size = 0;
	trace_count = 0;


	dialog_box->AddString("OPENING OLD FILE FORMAT");

	ar >> trace_count;
	++trace_count;
	
	traceCount = trace_count;

	dataArray = new CObArray;
	dataArray->SetSize(trace_count);

	CObarrayHolder *trace;

	BYTE bLetter; 
	char cLetter;
	BYTE trace_type;

	CFile *sample_file = ar.GetFile();


	for ( int i = 0; i < traceCount; ++i)
	{
		trace = new CObarrayHolder;
		dataArray->SetAt(i, trace);
		
		if ( i != (traceCount - 1))
		{
			ar >> trace_type;
			sample_start += 1;
			trace->traceType = trace_type;
			
	
			trace->name = "";
			ar >> bLetter;
			sample_start += 1;

			while(bLetter != NULL)
			{
				cLetter = bLetter;
				trace->name += cLetter;
				ar >> bLetter;
				sample_start += 1;
			}
			

			trace->traceEntryCount = 0;
		}
		else
		{
			trace->traceType = MarkerTraceType;
			trace->name = "Marker";
			trace->traceEntryCount = 0;
		}
	}

	ar >> sample_size;
	sample_start += 4;

	dialog_box->SetMaxCount(sample_size * 2);

	CObarrayHolder *data_holder;
	BYTE  trace_number;
	BYTE  edge_flag;
	WORD  edge_tick;
	float edge_fraction;
	LONG  integer_snap_shot;
	float scalar_snap_shot;
	LONG  total_bytes_read = 0;

	dialog_box->count = 0;
	
	MSG message;
	int message_count = 0;

	BOOL first_pass = TRUE;

	while ( total_bytes_read < sample_size )
	{
		int advance = 8;

		if (dialog_box->stopProcess == TRUE)
		{
			for (i = 0; i < traceCount; ++i)
			{
				data_holder = (CObarrayHolder*)dataArray->GetAt(i);
				data_holder->traceEntryCount = 0;
			}

			stillLoading = FALSE;
			//dialog_box->CancelRecived();
			
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}

		ar >> edge_fraction;
		ar >> edge_tick;
		ar >> trace_number;
		ar >> edge_flag;
		
		if (first_pass == TRUE)
		{
			first_pass = FALSE;
			firstTrace = SECONDS(edge_tick, edge_fraction);
			lastTrace = SECONDS(edge_tick, edge_fraction);
		}
		if (SECONDS(edge_tick, edge_fraction) < firstTrace)
		{
			firstTrace = SECONDS(edge_tick, edge_fraction);
		}
		if (SECONDS(edge_tick, edge_fraction) > lastTrace)
		{
			lastTrace = SECONDS(edge_tick, edge_fraction);
		}


		if (edge_flag == MarkerFlag)
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(traceCount - 1);
			
			data_holder->traceEntryCount += 1;

		}
		else
		{
			data_holder = (CObarrayHolder *)dataArray->GetAt(trace_number);
			data_holder->traceEntryCount += 1;
		}

		if (edge_flag == IntegerSnapShotFlag)
		{
			
			ar >> integer_snap_shot;
			advance += 4;
		}
		else if (edge_flag == ScalarSnapShotFlag)
		{
			
			ar >> scalar_snap_shot;
			advance += 4;
		}


		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;

		total_bytes_read += advance;
		dialog_box->count = total_bytes_read;
	}

	int total_size = 0;


	char number_buffer[20];


	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("ALLOCATING MEMORY");
	dialog_box->AddString("");

	char temp[100];


	dialog_box->AddString("Standard Trace Sizes:");

	ltoa( sizeof(TraceStorage), number_buffer, 10);
	strcpy(temp, "trace     size : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);
	

	ltoa(sizeof(MarkerTraceStorage),number_buffer,  10);
	strcpy(temp, "Marker    size : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);
	
	ltoa( sizeof(ToggleTraceStorage),number_buffer, 10);
	strcpy(temp, "Toggle    size : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);

	ltoa( sizeof(IntegerTraceStorage),number_buffer, 10);
	strcpy(temp, "Integer   size : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);

	ltoa(sizeof(ScalarTraceStorage), number_buffer, 10);
	strcpy(temp, "Scalar    size : ");
	strcat(temp, number_buffer);
	dialog_box->AddString(temp);





	dialog_box->AddString(" ");
	dialog_box->AddString("Trace List:");



	for (i = 0; i < traceCount; ++i)
	{
		data_holder = (CObarrayHolder*)dataArray->GetAt(i);

		if (data_holder->traceEntryCount == 0)
		{
			continue;
		}

		switch (data_holder->traceType)
		{

			case LogicalTraceType:
				data_holder->size = sizeof(ToggleTraceStorage) * data_holder->traceEntryCount;
		
				data_holder->data = (TraceStorage*)
					VirtualAlloc(NULL, data_holder->size, 
					MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);

				break;
			
			case IntegerTraceType:
				data_holder->size = sizeof(IntegerTraceStorage) * data_holder->traceEntryCount;
		
				data_holder->data = (TraceStorage*)
					VirtualAlloc(NULL, data_holder->size, 
					MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
				break;
			
			case ScalarTraceType:
				data_holder->size = sizeof(ScalarTraceStorage) * data_holder->traceEntryCount;
		
				data_holder->data = (TraceStorage*)
					VirtualAlloc(NULL, data_holder->size, 
					MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);
				break;
		
			case MarkerTraceType:
				data_holder->size = sizeof(MarkerTraceStorage) * data_holder->traceEntryCount;
		
				data_holder->data = (TraceStorage*)
					VirtualAlloc(NULL, data_holder->size, 
					MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, PAGE_READWRITE);

				break;
		}

	
		strcpy(temp, data_holder->name);
		strcat(temp, " - elements: ");
		ltoa( data_holder->traceEntryCount,number_buffer, 10); 
		strcat(temp, number_buffer);
		strcat(temp, " bytes : ");
		ltoa(data_holder->size, number_buffer, 10);
		strcat(temp, number_buffer);

		dialog_box->AddString(temp);
		

		data_holder->traceEntryCount = 0;
		total_size += data_holder->size;
	}

	dialog_box->AddString("");
	dialog_box->AddString("");

	ltoa(total_size, number_buffer, 10);
	dialog_box->AddString("TOTAL MEMORY ALLOCATED: ");
	dialog_box->AddString(number_buffer);
	dialog_box->AddString("");
	dialog_box->AddString("##############################");
	dialog_box->AddString("COPYING DATA INTO MEMORY");

	
	sample_file->Seek(sample_start, CFile::begin);
	
	message_count = 0;
	total_bytes_read = 0;

	while ( total_bytes_read < sample_size )
	{
		int advance = 8;

		if (dialog_box->stopProcess == TRUE)
		{
			stillLoading = FALSE;
			AfxThrowArchiveException(CArchiveException::badIndex);
			failedOpen = True;
			
			return;
		}

		ar >> edge_fraction;
		ar >> edge_tick;
		ar >> trace_number;
		ar >> edge_flag;

		if (edge_flag == IntegerSnapShotFlag)
		{
			ar >> integer_snap_shot;
			advance += 4;
		}
		else if (edge_flag == ScalarSnapShotFlag)
		{
			ar >> scalar_snap_shot;
			advance += 4;
		}
		
		
		if (edge_flag == MarkerFlag)
		{
			trace_number = (unsigned char)(traceCount - 1);
		}


		data_holder = (CObarrayHolder*)dataArray->GetAt(trace_number);


		TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(SECONDS(edge_tick, edge_fraction) - firstTrace);


		if (data_holder->traceEntryCount > 0)
		{
			if(TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->GetTraceTime() <
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount - 1)->GetTraceTime())
			{
				TraceStorage::FindElement(data_holder, data_holder->traceEntryCount)->SetTraceTime(SECONDS(edge_tick + 1, edge_fraction) - firstTrace);
			}
		}
	

		switch (data_holder->traceType)
		{
			case LogicalTraceType:
			{
				ToggleTraceStorage *entry = 
					(ToggleTraceStorage *) TraceStorage::FindElement(data_holder, data_holder->traceEntryCount);
				
				if (edge_flag == GoingUpFlag)
				{
					entry->SetPosition(TRUE);
				}
				else
				{
					entry->SetPosition(FALSE);
				}
				break;
			}
			case IntegerTraceType:
			{
				IntegerTraceStorage *entry = 
					(IntegerTraceStorage *)TraceStorage::FindElement(data_holder, data_holder->traceEntryCount);
				entry->SetPosition(integer_snap_shot);
				break;
			}
			case ScalarTraceType:
			{
				ScalarTraceStorage *entry = 
					(ScalarTraceStorage *)TraceStorage::FindElement(data_holder, data_holder->traceEntryCount);
					entry->SetPosition(scalar_snap_shot);
				break;
			}
		}

		data_holder->traceEntryCount += 1;


		if (message_count > 800)
		{
			message_count = 0;
			if (::PeekMessage(&message, NULL,0,0, PM_REMOVE)) 
			{
				::TranslateMessage(&message);
				::DispatchMessage(&message);
			}
		}

		++message_count;


		total_bytes_read += advance;
		dialog_box->count = total_bytes_read + sample_size;
	}

	lastTrace -= firstTrace;
	firstTrace = 0.0f;

	stillLoading = FALSE;

}

/////////////////////////////////////////////////////////////////////////////
// CLabRatDoc diagnostics

#ifdef _DEBUG
void CLabRatDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CLabRatDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CLabRatDoc commands

BOOL CLabRatDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
	if (!CDocument::OnOpenDocument(lpszPathName))
		return FALSE;
	
	if (failedOpen)
		return False;
	
	return TRUE;
}

void CLabRatDoc::DeleteContents() 
{
	// TODO: Add your specialized code here and/or call the base class
	
	CDocument::DeleteContents();

	if (dataArray != NULL)
	{
		CObarrayHolder *delete_me;
		for (int i = 0; i < traceCount; ++i)
		{
			delete_me = (CObarrayHolder *)dataArray->GetAt(i);
			delete(delete_me);	
		}
		delete dataArray;
	}

	if (classIDList != NULL)
	{

		ClassIDList *pos;
		CObjString *st_pos;	
	
		while (!classIDList->IsEmpty())
		{
		    
			pos = (ClassIDList *)classIDList->RemoveHead();

			for(int i = 0; i < pos->messageCount; ++i)
			{
				st_pos = (CObjString *)pos->messageList->GetAt(i);
				delete st_pos;
			}
			pos->messageList->RemoveAll();
			delete pos->messageList;
			delete pos;
		}	

		classIDList->RemoveAll();
		delete classIDList;
	}

}

ClassIDList *CLabRatDoc::FindClass(int id)
{

	ClassIDList *class_list;
	POSITION pos = classIDList->GetHeadPosition();

	while(pos != NULL)
	{
		class_list = (ClassIDList *) classIDList->GetNext(pos);
		
		if (class_list->classID == id)
		{
			return class_list;
		}
	}
	
	return NULL;
}
