//===========================================================================//
// File:    traceline.cpp                                                     
// Project: LabRat                                                 		 
// Contents: 				  
//---------------------------------------------------------------------------//
//   Date    Who  Modification                                               //
// --------  ---  ---------------------------------------------------------- //
// 03/20/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 "traceline.hpp"



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

//##########################################################################
//#######################    TraceLine    
//##########################################################################


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

TraceLine::TraceLine(void)
{
	startTime = 0.0f;
	endTime = 0.0f;
	timeToPixel = 0.0f;
	firstTraceIndex = 0;
	lastTraceIndex = 0;
	dataHolder = NULL;
	document = NULL;
	traceNumber = -1;
	on = True;
	alreadyWorking = FALSE;
	traceMade = False;

	traceColor.red = 0;
	traceColor.green = 0;
	traceColor.blue = 0;

	traceHeight = DEFAULT_SIZE;

	selected = False;	
	startSelection = 0.0f,
	endSelection = 0.0f;

}

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

TraceLine::~TraceLine(void)
{

}

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

int TraceLine::GetTraceType()
{
	return CLabRatDoc::DefaultTraceType;
}

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

void
	TraceLine::Draw(int /*offset*/)
{

}



void
	TraceLine::DrawName(int offset)
{
	MY_RGB grey;
	grey.red = 128; grey.blue = 128; grey.green = 128;
	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;

	int size = CalculateSize();
	int half_size = (int)(size * 0.5f);

	

	if (selected)
	{
		CRect box;
	
		box.left = 0;
		box.top = offset;
		box.bottom = offset + size;
		box.right = myParent->nameSize.Width();
		
		myParent->DrawCRect(box, grey);
	}


	CPoint to, from;

	to.x = 0;
	to.y = offset;
	from.x = myParent->nameSize.Width();
	from.y = offset;
	myParent->DrawLine(to, from, light_grey, 1);

	to.x = 0;
	to.y = offset + size;
	from.x = myParent->nameSize.Width();
	from.y = offset + size;
	

	if(selected)
	{
		myParent->DrawLine(to, from, black, 1);
	}
	else
	{
		myParent->DrawLine(to, from, grey, 1);
	}


	if (on)
	{
		if (selected)
		{
			myParent->DrawText(traceName, 0, offset+size-2, white);
		}
		else
		{
			myParent->DrawText(traceName, 0, offset+size-2, black);
		}
	}
	else
	{
		myParent->DrawText(traceName, 0, offset+size-2, light_grey);
	}
}


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

void
	TraceLine::DrawLine(int offset)
{
	MY_RGB grey;
	grey.red = 128; grey.blue = 128; grey.green = 128;
	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;

	int size = CalculateSize();
	int half_size = (int)(size * 0.5f);

	
#if 0
	if (selected)
	{
		CRect box;
	
		box.left = myParent->logicSize.left;
		box.top = offset;
		box.bottom = offset + size;
		box.right = myParent->logicSize.right;
		
		myParent->DrawCRect(box, grey);
	}
#endif

	CPoint to, from;

	to.x = myParent->logicSize.left;
	to.y = offset;
	from.x = myParent->logicSize.right;
	from.y = offset;
	myParent->DrawLine(to, from, light_grey, 1);

	to.x = myParent->logicSize.left;
	to.y = offset + size;
	from.x = myParent->logicSize.right;
	from.y = offset + size;

#if 0
	if(selected)
	{
		myParent->DrawLine(to, from, black, 1);
	}
	else
#endif
	{
		myParent->DrawLine(to, from, grey, 1);
	}

}



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

void
	TraceLine::DrawCurrentValue(int offset, Time /*timeOfValue*/)
{

	MY_RGB grey;
	grey.red = 128; grey.blue = 128; grey.green = 128;
	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;

	int size = CalculateSize();
	int half_size = (int)(size * 0.5f);

#if 0
	if (selected)
	{
		CRect box;
	
		box.left = myParent->valueSize.left;
		box.top = offset;
		box.bottom = offset + size;
		box.right = myParent->valueSize.right;
		
		myParent->DrawCRect(box, grey);
	}
#endif

	CPoint to, from;

	to.x = myParent->valueSize.left;
	to.y = offset;
	from.x = myParent->valueSize.right;
	from.y = offset;
	myParent->DrawLine(to, from, light_grey, 1);

	to.x = myParent->valueSize.left;
	to.y = offset + size;
	from.x = myParent->valueSize.right;
	from.y = offset + size;

#if 0
	if(selected)
	{
		myParent->DrawLine(to, from, black, 1);
	}
	else
#endif
	{
		myParent->DrawLine(to, from, grey, 1);
	}

}

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

int
	TraceLine::CalculateSize(void)
{
	return traceHeight;
}

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

Logical
	TraceLine::MakeTrace(
		Time start_time, 
		Time end_time,
		Time time_to_pixel
		)
{

	if (!on )
	{
		return FALSE;
	}

	if ( dataHolder->traceEntryCount != 0 )
	{

		if ( (start_time >= startTime) && (end_time <= endTime) && (time_to_pixel == timeToPixel))
		{	
			// your still in the current trace range..
			return FALSE;
		}

		timeToPixel = time_to_pixel;
		//
		// else make the pages larger than requested by the view...
		//

		Time span = end_time - start_time;
		
		span = span * 0.5f;

		// store 2 pages of data... .5 before and .5 after
		start_time -= span;
		end_time += span;
		
		//
		// if your too far give the other side your bonus...
		//

		if (start_time < document->firstTrace)
		{
			Time diffrence = document->firstTrace - start_time;
			end_time += diffrence;
		}

		if (end_time > document->lastTrace)
		{
			Time diffrence = end_time - document->lastTrace;
			start_time -= diffrence;
		}

		//
		// Now that we have our bonuses, cap ourselves
		//
		Min_Clamp(start_time, document->firstTrace);
		Max_Clamp(end_time, document->lastTrace);	


		startTime = start_time;
		endTime = end_time;



		

		if ( TraceStorage::FindElement(dataHolder, firstTraceIndex)->GetTraceTime() < start_time)
		{
			int i;
			for(i = firstTraceIndex; i < dataHolder->traceEntryCount; ++i)
			{
				
				if ( TraceStorage::FindElement(dataHolder, i)->GetTraceTime() > start_time)
				{
					//
					// Keep one before the screen start
					//
					
					i -= 1;
					Min_Clamp(i, 0);
					firstTraceIndex = i;
					break;
				}
			}
			if (i == dataHolder->traceEntryCount)
			{
				i = dataHolder->traceEntryCount-1;
				firstTraceIndex = i;
			}
		}
		else if ( TraceStorage::FindElement(dataHolder, firstTraceIndex)->GetTraceTime() > start_time)
		{
			int i;
			for(i = firstTraceIndex; i >= 0; --i)
			{
				if ( TraceStorage::FindElement(dataHolder, i)->GetTraceTime() < start_time)
				{
					
					Min_Clamp(i, 0);
					firstTraceIndex = i;
					break;
				}
			}
			if (i == -1)
			{
				i = 0;
				firstTraceIndex = i;
			}
		}
		
		//
		// Else, it's us!!!


		// 
		// find last trace
		//


		if ( TraceStorage::FindElement(dataHolder, lastTraceIndex)->GetTraceTime() < end_time)
		{	
			int i;
			for(i = lastTraceIndex; i < dataHolder->traceEntryCount; ++i)
			{
				if ( TraceStorage::FindElement(dataHolder, i)->GetTraceTime() > end_time)
				{
					Max_Clamp(i, dataHolder->traceEntryCount-1);
					lastTraceIndex = i;
					break;
				}
			}
			if (i == dataHolder->traceEntryCount)
			{
				i = dataHolder->traceEntryCount-1;
				lastTraceIndex = i;
			}

		}
		else if ( TraceStorage::FindElement(dataHolder, lastTraceIndex)->GetTraceTime() > end_time)
		{
			for(int i = lastTraceIndex; i >= 0; --i)
			{
				if ( TraceStorage::FindElement(dataHolder, i)->GetTraceTime() < end_time)
				{
					//
					// Keep one before the screen start
					//
					++i;
					Max_Clamp(i, dataHolder->traceEntryCount-1);
					lastTraceIndex = i;
					break;
				}
			}
			if (i == -1)
			{
				i = 0;
				lastTraceIndex = i;
			}
		}
	}
	
	traceMade = True;

	return TRUE;
}

//##########################################################################
//#######################    ToggleTraceLine    
//##########################################################################
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ToggleTraceLine::ToggleTraceLine(void)
{
	traceHeight = TOGGLE_SIZE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

ToggleTraceLine::~ToggleTraceLine(void)
{

}

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

int ToggleTraceLine::GetTraceType()
{
	return CLabRatDoc::LogicalTraceType;
}

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

void
	ToggleTraceLine::DrawCurrentValue(int offset, Time timeOfValue)
{


	TraceLine::DrawCurrentValue(offset, timeOfValue);

	if(!traceMade)
	{
		return;
	}

	if (!on)
	{
		return;
	}

	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	

	MY_RGB red;
	red.red = 255; red.blue = 0; red.green = 0;
	MY_RGB green;
	green.red = 0; green.blue = 0; green.green = 192;


	int i = firstTraceIndex;

	int value = 0;

	while (i <= lastTraceIndex)
	{	
		Time current_time = TraceStorage::FindElement(dataHolder, i)->GetTraceTime();
		
		if (current_time > timeOfValue)
		{
			break;
		}
		else
		{
			ToggleTraceStorage *trace = (ToggleTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
			value = trace->GetPosition();
			++i;
		}
	}


	CString value_text;


	if(!value)
	{
		value_text = "OFF";
	}
	else
	{
		value_text = "ON";
	}


	int size = CalculateSize();

	
	if (value)
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, red);
	}
	else
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, green);
	}
	
	



}

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

void
	ToggleTraceLine::Draw(int offset)
{


	//TRACE("trace %d - ttp %f\n", traceNumber, timeToPixel);
	TraceLine::Draw(offset);

	DrawLine(offset);

	if (!on)
	{
		return;
	}

	int counter = 0;
	int mode_counter = 0;

	int size = CalculateSize();

	Time 
		last_time, 
		now_time;

	BOOL
		last_value,
		now_value;

	//TRACE("%f :-: %f\n",view->startTime, view->endTime);
	

	Time
		start_box_time;
	BOOL
		start_box_value;

	while(traceArray[counter] != -1)
	{
												
		ToggleTraceStorage *trace = (ToggleTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter]));
	
		now_time = trace->GetTraceTime();
		now_value = trace->GetPosition();


		if (counter == 0) // first trace
		{
			last_value = now_value;
			last_time = myParent->viewedTime.startTime;
		}
		else
		{
			ToggleTraceStorage *last_trace = (ToggleTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter-1]));
			last_time = last_trace->GetTraceTime();
			last_value = last_trace->GetPosition();
		}

		int last_value_pixel = 0;
		int now_value_pixel = 0;

		if (last_value == CLabRatDoc::GoingUpFlag)
		{
			last_value_pixel = 0;
		}
		else
		{
			last_value_pixel = -traceHeight;
		}

		if (last_value == CLabRatDoc::GoingDownFlag)
		{
			now_value_pixel = 0;
		}
		else
		{
			now_value_pixel = -traceHeight;
		}



		Logical draw = FALSE;

		if ((now_time >= myParent->viewedTime.startTime) && (now_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time >= myParent->viewedTime.startTime) && (last_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time <= myParent->viewedTime.startTime) && (now_time >= myParent->viewedTime.endTime))
		{
			draw = True;
		}


		//
		// If this is an start box,  save it.
		// If this is the end, use saved values...
		//
		if (traceMode[mode_counter] == StartBox)
		{
				start_box_time = now_time;
				start_box_value = now_value;
		}
		else if (traceMode[mode_counter] == EndBox)
		{
				last_time = start_box_time;
				last_value = start_box_value;
		}
		
		
		if (draw)
		{
			Time offset_time = myParent->viewedTime.pixelToTime * myParent->logicSize.left;

			
			if (traceMode[mode_counter] == DoubleTrace)
			{
				//TRACE("DOUBLE\n");
			
				int new_offset = CalculateSize() + offset;


				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						-(traceHeight-1), 0, 
						new_offset, traceColor, 2);
				
				
			}
			else if (traceMode[mode_counter] == DrawTrace)
			{
				//TRACE("SINGLE\n");
			
				int new_offset = CalculateSize() + offset;

				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);
				
				myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
						last_value_pixel, last_value_pixel, 
						new_offset, traceColor, 1);


			}
			else if (traceMode[mode_counter] == EndBox)
			{
				//TRACE("BOX\n");
				
				
				
				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);

				int new_offset = CalculateSize() + offset;
				
				

				myParent->DrawBox(last_time + offset_time, now_time + offset_time, 
							-traceHeight, 
							0, 
							new_offset, traceColor);

			}
			if (traceMode[mode_counter] == StartBox)
			{
				//TRACE("DOUBLE\n");

				// save this info for the end of the box
				



				int new_offset = CalculateSize() + offset;

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);

				myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
					last_value_pixel, last_value_pixel, 
					new_offset, traceColor, 1);
				
			}
		
		}
		
		++mode_counter;
		++counter;
	}
	

}

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

int
	ToggleTraceLine::CalculateSize(void)
{

	//
	// Return my bounding box size, not including a border
	//

	return traceHeight;
}


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

Logical
	ToggleTraceLine::MakeTrace(
		Time start_time, 
		Time end_time,
		Time time_to_pixel)
{

	if (!on)
	{
		return FALSE;
	}

	if ( alreadyWorking == TRUE )
	{
		return FALSE;
	}
	else
	{
		alreadyWorking = TRUE;
	}


	

	int start_trace = 0;
	int mode_counter = 0;

	if ( dataHolder->traceEntryCount != 0 )
	{
	
		if (TraceLine::MakeTrace(start_time, end_time, time_to_pixel))
		{

			Time temp_time_to_pixel = timeToPixel;
			
			traceArray[start_trace] = -1;

			
			int i;
			int last_pixel = -1000;

			// Pick out all the traces visable

			Logical drawing_box = FALSE;
			int diffrence;

			i = firstTraceIndex;

			while (i <= lastTraceIndex)
			{
			
				int this_pixel = (int)(temp_time_to_pixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
		

				if (start_trace >= TOGGLE_ARRAY_SIZE)
				{
					TRACE("START TRACE WAY TO BIG!!!!!!!!!!!!!! traceline.cpp ln:309\n");
				}

				Max_Clamp(start_trace, TOGGLE_ARRAY_SIZE);
				

				diffrence = this_pixel - last_pixel;
				if (diffrence <= BOX_MINIMUM)
				{
					//TRACE("BOX\n");
					int box_start_pix;
					int box_end_pix;
					
					box_start_pix = last_pixel;
					box_end_pix = this_pixel;
							
					last_pixel = this_pixel;
					traceArray[start_trace] = i;
					traceMode[mode_counter-1] = StartBox;
					traceMode[mode_counter] = EndBox;
					++start_trace;
					++mode_counter;

					++i;

					while(i <= lastTraceIndex)
					{
						this_pixel = (int)(temp_time_to_pixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
						
						diffrence = this_pixel - last_pixel;
						if (diffrence <= BOX_MINIMUM)
						{
							// keep going
							--start_trace;
							--mode_counter;

							box_end_pix = this_pixel;
							last_pixel = this_pixel;
							traceArray[start_trace] = i;
							traceMode[mode_counter] = EndBox;
							++start_trace;
							++mode_counter;
							++i;
						}
						else
						{		
							//int result = Abs(box_start_pix - box_end_pix);
							int result = Abs(box_end_pix - box_start_pix);

							if (result <= 1)
							{
								traceMode[mode_counter-1] = DoubleTrace;
							}
							break;
						}
					}
					if (i > lastTraceIndex)
					{
	
						//int result = Abs(box_start_pix - box_end_pix);
						int result = Abs(box_end_pix - box_start_pix);


						if (result <= 1)
						{
							traceMode[mode_counter-1] = DoubleTrace;
						}
						break;
					}
				}
				else
				{
					
					last_pixel = this_pixel;
					traceArray[start_trace] = i;
					traceMode[mode_counter] = DrawTrace;
					++start_trace;
					++mode_counter;
					++i;


		

				}
			}


			traceArray[start_trace] = -1;
			
		}
	}
	else
	{
		traceArray[start_trace] = -1;
	}

	alreadyWorking = FALSE;

	return TRUE;
	
}

//##########################################################################
//#######################    MarkerTraceLine    
//##########################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
MarkerTraceLine::MarkerTraceLine(void)
{
	traceColor.red = 0;
	traceColor.green = 0;
	traceColor.blue = 255;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

MarkerTraceLine::~MarkerTraceLine(void)
{

}

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

int MarkerTraceLine::GetTraceType()
{
	return CLabRatDoc::MarkerTraceType;
}

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

void
	MarkerTraceLine::Draw(int /*offset*/ )
{
	// Don't draw my name or my pulse... =)

	if (!on)
	{
		return;
	}

	int counter = 0;

	Time offset_time = myParent->viewedTime.pixelToTime * myParent->logicSize.left;

	
	while(traceArray[counter] != -1)
	{



		TraceStorage *trace = (TraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter]));
	
		Time marker_time = trace->GetTraceTime();

		myParent->DrawLine(marker_time + offset_time, marker_time + offset_time, 
				myParent->logicSize.top, myParent->logicSize.bottom, 
				0, traceColor, 1);
		++counter;
	}

}


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

Logical
	MarkerTraceLine::MakeTrace(
		Time start_time, 
		Time end_time,
		Time time_to_pixel)
{

	if (!on)
	{
		return FALSE;
	}
	
	if ( alreadyWorking == TRUE )
	{
		return FALSE;
	}
	else
	{
		alreadyWorking = TRUE;
	}


	int start_trace = 0;

	if ( dataHolder->traceEntryCount != 0 )
	{
	
		if (TraceLine::MakeTrace(start_time, end_time, time_to_pixel))
		{
			
			traceArray[start_trace] = -1;

			int last_pixel = -1000;

			for (int i = firstTraceIndex; i <= lastTraceIndex; ++i)
			{
				int this_pixel = (int)(timeToPixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
				

				if (this_pixel != last_pixel)
				{
					traceArray[start_trace] = i;
					++start_trace;
				}
			}

			traceArray[start_trace] = -1;
		}
	}
	else
	{
		traceArray[start_trace] = -1;
	}

	alreadyWorking = FALSE;

	return TRUE;

}

//##########################################################################
//#######################   IntegerTraceLine    
//##########################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
IntegerTraceLine::IntegerTraceLine(void)
{

	min = 0;
	max = 0;
	adjustToZero = 0;
	valueToPixel = 0.0f;
	traceHeight = INTEGER_SIZE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

IntegerTraceLine::~IntegerTraceLine(void)
{

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

int
	IntegerTraceLine::CalculateSize(void)
{

	return traceHeight;

}


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

int IntegerTraceLine::GetTraceType()
{
	return CLabRatDoc::IntegerTraceType;
}

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

void
	IntegerTraceLine::DrawCurrentValue(int offset, Time timeOfValue)
{


	TraceLine::DrawCurrentValue(offset, timeOfValue);

	if(!traceMade)
	{
		return;
	}
	if(!on)
	{
		return;
	}

	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;


	int i = firstTraceIndex;

	int value = 0;

	while (i <= lastTraceIndex)
	{	
		Time current_time = TraceStorage::FindElement(dataHolder, i)->GetTraceTime();
		
		if (current_time > timeOfValue)
		{
			break;
		}
		else
		{
			IntegerTraceStorage *trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
			value = trace->GetPosition();
			++i;
		}
	}


	char value_text[20];

	sprintf(value_text, "%d", value);


	int size = CalculateSize();

#if 0
	if (selected)
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, white);
	}
	else
#endif
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, black);
	}
	



}

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

void
	IntegerTraceLine::Draw(int offset)
{


	TraceLine::Draw(offset);
	DrawLine(offset);


	if (!on)
	{
		return;
	}

	int counter = 0;

	int size = CalculateSize();

	Time 
		last_time, 
		now_time;

	int
		last_value,
		now_value;

	int
		save_first_value;

	while(traceArray[counter] != -1)
	{

		IntegerTraceStorage *trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter]));
	
		now_time = trace->GetTraceTime();
		now_value = trace->GetPosition();


		if (counter == 0) // first trace
		{
			last_value = now_value;
			last_time = myParent->viewedTime.startTime;
		}
		else
		{
			IntegerTraceStorage *last_trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter-1]));
			last_time = last_trace->GetTraceTime();
			last_value = last_trace->GetPosition();
		}

		int last_value_pixel = 0;
		int now_value_pixel = 0;

		
		int new_offset = CalculateSize() + offset;


		last_value_pixel = (int)(-(valueToPixel * (last_value + adjustToZero)));
		now_value_pixel = (int)(-(valueToPixel * (now_value + adjustToZero)));


		Logical draw = FALSE;

		if ((now_time >= myParent->viewedTime.startTime) && (now_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time >= myParent->viewedTime.startTime) && (last_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time <= myParent->viewedTime.startTime) && (now_time >= myParent->viewedTime.endTime))
		{
			draw = True;
		}



		if (traceMode[counter] == MaxTrace)
		{
			if (traceMode[counter-1] != MinTrace)
			{
				TRACE("MAX WITHOUT MIN\n");
			}
		}
		if (traceMode[counter] == MinTrace)
		{
			if (traceMode[counter-1] != StartDouble)
			{
				TRACE("MIN WITHOUT STARTDOUBLE\n");
			}
		}
		if (traceMode[counter] == EndDouble)
		{
			if (traceMode[counter-1] != MaxTrace)
			{
				TRACE("END WITHOUT MAX\n");
			}
		}


		if (traceMode[counter] == StartDouble)
		{
			save_first_value = last_value_pixel;
		}
		if (traceMode[counter] == EndDouble)
		{
			last_value_pixel = save_first_value;
		}


		if (draw)
		{
			Time offset_time = myParent->viewedTime.pixelToTime * myParent->logicSize.left;

			if (traceMode[counter] == DrawTrace)
			{
				//TRACE("SINGLE\n");
			
				
				myParent->DrawLine(now_time+ offset_time, now_time+ offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);
				
				myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
						last_value_pixel, last_value_pixel, 
						new_offset, traceColor, 1);
			}
			else if (traceMode[counter] == StartDouble)
			{

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);
				

				int last_pix =(int) ((last_time - myParent->viewedTime.startTime) * myParent->viewedTime.timeToPixel);
				int now_pix =(int) ((now_time - myParent->viewedTime.startTime) * myParent->viewedTime.timeToPixel);

				//int diffrence = now_pix - last_pix;
				//if (Abs(diffrence) > 0)
				{
					myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
							last_value_pixel, last_value_pixel, 
							new_offset, traceColor, 1);
				}

			}
			else if (traceMode[counter] == MaxTrace)
			{
				// Draw max trace
				// the last one was a min trace

				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				
			}
			else if (traceMode[counter] == EndDouble)
			{
				// Draw max trace
				// the last one was a min trace

				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				
			}

		
			// if it is a min ignore it, next trace uses it.
			// if it is a enddouble ignore, next trace uses it
		}
		
		++counter;
	}

}

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

void
	IntegerTraceLine::SetMinMax(void)
{

	Logical first_pass = TRUE;

	for ( int i = 0; i < dataHolder->traceEntryCount; ++i)
	{
		IntegerTraceStorage *trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
		if (first_pass)
		{
			first_pass = FALSE;
			min = trace->GetPosition();
			max = trace->GetPosition();
		}
		else
		{
			if (trace->GetPosition() < min)
			{
				min = trace->GetPosition();
			}
			
			if (trace->GetPosition() > max)
			{
				max = trace->GetPosition();
			}
		}

	}

	adjustToZero = 0 - min;
	
	if (max == min)
	{
		valueToPixel = 0.0f;
	}
	else
	{
		valueToPixel = (float)traceHeight / (float)(max - min);
	}

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

Logical
	IntegerTraceLine::MakeTrace(
		Time start_time, 
		Time end_time,
		Time time_to_pixel)
{


	if (!on)
	{
		return FALSE;
	}

	if ( alreadyWorking == TRUE )
	{
		return FALSE;
	}
	else
	{
		alreadyWorking = TRUE;
	}


	int start_trace = 0;

	if ( dataHolder->traceEntryCount != 0 )
	{
	
		if (TraceLine::MakeTrace(start_time, end_time, time_to_pixel))
		{
			
			traceArray[start_trace] = -1;

			int last_pixel = -1000;

			int i = firstTraceIndex;

			while ( i <= lastTraceIndex)
			{

				if (start_trace >= INTEGER_ARRAY_SIZE)
				{
					TRACE("START TRACE WAY TO BIG!!!!!!!!!!!!!! traceline.cpp ln:1100\n");
				}

				Max_Clamp(start_trace, INTEGER_ARRAY_SIZE);
				

				int this_pixel = (int)(timeToPixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
				
				if (this_pixel != last_pixel)
				{
					last_pixel = this_pixel;
					traceArray[start_trace] = i;
					traceMode[start_trace] = DrawTrace;
					++start_trace;
					++i;
				}
				else
				{
									
					int start_index, stop_index, min_index, max_index;
					int start_i, stop_i, min_i, max_i;
					int temp_pixel = this_pixel;


					

					start_index = start_trace - 1;
					min_index = start_trace;
					max_index = start_trace + 1;
					stop_index = start_trace + 2;
					start_trace += 3;

					if (start_trace >= INTEGER_ARRAY_SIZE)
					{
						TRACE("START TRACE WAY TO BIG!!!!!!!!!!!!!! traceline.cpp ln:1134\n");
					}

					Max_Clamp(start_trace, INTEGER_ARRAY_SIZE);
				

					start_i = traceArray[start_index];
					stop_i = i;


					IntegerTraceStorage *trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
					IntegerTraceStorage *start_trace_storage = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[start_index]));
					
					
					if (trace->GetPosition() < start_trace_storage->GetPosition())
					{
						min_i = i;
						max_i = start_i;

					}
					else
					{
						max_i = i;
						min_i = start_i;

					}

					

					while (temp_pixel == this_pixel)
					{
						
						IntegerTraceStorage *min_trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, min_i));
						IntegerTraceStorage *max_trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, max_i));
		
						if (trace->GetPosition() < min_trace->GetPosition())
						{
							min_i = i;
						}
						if (trace->GetPosition() > max_trace->GetPosition())
						{
							max_i = i;
						}

						stop_i = i;
						

						++i;
						if (i > lastTraceIndex)
						{
							break;
						}
						temp_pixel = (int)(timeToPixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
						trace = (IntegerTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
					}

					traceArray[start_index] = start_i; 
					traceMode[start_index] = StartDouble;

					traceArray[min_index] = min_i;
					traceMode[min_index] = MinTrace;
					
					traceArray[max_index] = max_i;
					traceMode[max_index] = MaxTrace;
					
					traceArray[stop_index] = stop_i;
					traceMode[stop_index] = EndDouble;

				}
			}

			traceArray[start_trace] = -1;
		}
	}
	else
	{
		traceArray[start_trace] = -1;
	}

	alreadyWorking = FALSE;

	return TRUE;


}

//##########################################################################
//#######################   ScalarTraceLine    
//##########################################################################

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ScalarTraceLine::ScalarTraceLine(void)
{

	min = 0.0f;
	max = 0.0f;
	adjustToZero = 0.0f;
	valueToPixel = 0.0f;
	traceHeight = SCALAR_SIZE;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

ScalarTraceLine::~ScalarTraceLine(void)
{

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

int ScalarTraceLine::GetTraceType()
{
	return CLabRatDoc::ScalarTraceType;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
	ScalarTraceLine::CalculateSize(void)
{

	return traceHeight;

}


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


void
	ScalarTraceLine::DrawCurrentValue(int offset, Time timeOfValue)
{


	TraceLine::DrawCurrentValue(offset, timeOfValue);

	if(!traceMade)
	{
		return;
	}
	if(!on)
	{
		return;
	}

	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;


	int i = firstTraceIndex;

	Scalar value = 0.0f;

	while (i <= lastTraceIndex)
	{	
		Time current_time = TraceStorage::FindElement(dataHolder, i)->GetTraceTime();
		
		if (current_time > timeOfValue)
		{
			break;
		}
		else
		{
			ScalarTraceStorage *trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
			value = trace->GetPosition();
			++i;
		}
	}


	char value_text[20];

	sprintf(value_text, "%f", value);


	int size = CalculateSize();

#if 0
	if (selected)
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, white);
	}
	else
#endif
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, black);
	}



}

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

void
	ScalarTraceLine::Draw(int offset)
{


	TraceLine::Draw(offset);
	DrawLine(offset);


	if (!on)
	{
		return;
	}

	int counter = 0;

	int size = CalculateSize();

	Time 
		last_time, 
		now_time;

	Scalar
		last_value,
		now_value;

	int
		save_first_value;

	while(traceArray[counter] != -1)
	{

		ScalarTraceStorage *trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter]));
	
		now_time = trace->GetTraceTime();
		now_value = trace->GetPosition();


		if (counter == 0) // first trace
		{
			last_value = now_value;
			last_time = myParent->viewedTime.startTime;
		}
		else
		{
			ScalarTraceStorage *last_trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[counter-1]));
			last_time = last_trace->GetTraceTime();
			last_value = last_trace->GetPosition();
		}

		int last_value_pixel = 0;
		int now_value_pixel = 0;

		
		int new_offset = CalculateSize() + offset;


		last_value_pixel = (int)(-(valueToPixel * (last_value + adjustToZero)));
		now_value_pixel = (int)(-(valueToPixel * (now_value + adjustToZero)));


		Logical draw = FALSE;

		if ((now_time >= myParent->viewedTime.startTime) && (now_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time >= myParent->viewedTime.startTime) && (last_time <= myParent->viewedTime.endTime))
		{
			draw = True;
		}
		else if ((last_time <= myParent->viewedTime.startTime) && (now_time >= myParent->viewedTime.endTime))
		{
			draw = True;
		}



		if (traceMode[counter] == MaxTrace)
		{
			if (traceMode[counter-1] != MinTrace)
			{
				TRACE("MAX WITHOUT MIN\n");
			}
		}
		if (traceMode[counter] == MinTrace)
		{
			if (traceMode[counter-1] != StartDouble)
			{
				TRACE("MIN WITHOUT STARTDOUBLE\n");
			}
		}
		if (traceMode[counter] == EndDouble)
		{
			if (traceMode[counter-1] != MaxTrace)
			{
				TRACE("END WITHOUT MAX\n");
			}
		}


		if (traceMode[counter] == StartDouble)
		{
			save_first_value = last_value_pixel;
		}
		if (traceMode[counter] == EndDouble)
		{
			last_value_pixel = save_first_value;
		}


		if (draw)
		{
			Time offset_time = myParent->viewedTime.pixelToTime * myParent->logicSize.left;

			if (traceMode[counter] == DrawTrace)
			{
				//TRACE("SINGLE\n");
			
				
				myParent->DrawLine(now_time+ offset_time, now_time+ offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);
				
				myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
						last_value_pixel, last_value_pixel, 
						new_offset, traceColor, 1);
			}
			else if (traceMode[counter] == StartDouble)
			{

				Min_Clamp(now_time, myParent->viewedTime.startTime);
				Max_Clamp(now_time, myParent->viewedTime.endTime);
				
				Min_Clamp(last_time, myParent->viewedTime.startTime);
				Max_Clamp(last_time, myParent->viewedTime.endTime);
				

				int last_pix =(int) ((last_time - myParent->viewedTime.startTime) * myParent->viewedTime.timeToPixel);
				int now_pix =(int) ((now_time - myParent->viewedTime.startTime) * myParent->viewedTime.timeToPixel);

				//int diffrence = now_pix - last_pix;
				//if (Abs(diffrence) > 0)
				{
					myParent->DrawLine(last_time + offset_time, now_time + offset_time, 
							last_value_pixel, last_value_pixel, 
							new_offset, traceColor, 1);
				}

			}
			else if (traceMode[counter] == MaxTrace)
			{
				// Draw max trace
				// the last one was a min trace

				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				
			}
			else if (traceMode[counter] == EndDouble)
			{
				// Draw max trace
				// the last one was a min trace

				myParent->DrawLine(now_time + offset_time, now_time + offset_time, 
						last_value_pixel, now_value_pixel, 
						new_offset, traceColor, 1);
				
			}

		
			// if it is a min ignore it, next trace uses it.
			// if it is a enddouble ignore, next trace uses it
		}
		
		++counter;
	}

}

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

void
	ScalarTraceLine::SetMinMax(void)
{

	Logical first_pass = TRUE;

	for ( int i = 0; i < dataHolder->traceEntryCount; ++i)
	{
		ScalarTraceStorage *trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
		if (first_pass)
		{
			first_pass = FALSE;
			min = trace->GetPosition();
			max = trace->GetPosition();
		}
		else
		{
			if (trace->GetPosition() < min)
			{
				min = trace->GetPosition();
			}
			
			if (trace->GetPosition() > max)
			{
				max = trace->GetPosition();
			}
		}

	}

	adjustToZero = 0 - min;
	
	if (max == min)
	{
		valueToPixel = 0.0f;
	}
	else
	{
		valueToPixel = (float)traceHeight / (float)(max - min);
	}

}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//

Logical
	ScalarTraceLine::MakeTrace(
		Time start_time, 
		Time end_time,
		Time time_to_pixel)
{


	if (!on)
	{
		return FALSE;
	}

	if ( alreadyWorking == TRUE )
	{
		return FALSE;
	}
	else
	{
		alreadyWorking = TRUE;
	}


	int start_trace = 0;

	if ( dataHolder->traceEntryCount != 0 )
	{
	
		if (TraceLine::MakeTrace(start_time, end_time, time_to_pixel))
		{
			
			traceArray[start_trace] = -1;

			int last_pixel = -1000;

			int i = firstTraceIndex;

			while ( i <= lastTraceIndex)
			{

				if (start_trace >= SCALAR_ARRAY_SIZE)
				{
					TRACE("START TRACE WAY TO BIG!!!!!!!!!!!!!! traceline.cpp ln:1100\n");
				}

				Max_Clamp(start_trace, SCALAR_ARRAY_SIZE);
				

				int this_pixel = (int)(timeToPixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
				
				if (this_pixel != last_pixel)
				{
					last_pixel = this_pixel;
					traceArray[start_trace] = i;
					traceMode[start_trace] = DrawTrace;
					++start_trace;
					++i;
				}
				else
				{
									
					int start_index, stop_index, min_index, max_index;
					int start_i, stop_i, min_i, max_i;
					int temp_pixel = this_pixel;


					

					start_index = start_trace - 1;
					min_index = start_trace;
					max_index = start_trace + 1;
					stop_index = start_trace + 2;
					start_trace += 3;

					if (start_trace >= SCALAR_ARRAY_SIZE)
					{
						TRACE("START TRACE WAY TO BIG!!!!!!!!!!!!!! traceline.cpp ln:1134\n");
					}

					Max_Clamp(start_trace, SCALAR_ARRAY_SIZE);
				

					start_i = traceArray[start_index];
					stop_i = i;


					ScalarTraceStorage *trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
					ScalarTraceStorage *start_trace_storage = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, traceArray[start_index]));
					
					
					if (trace->GetPosition() < start_trace_storage->GetPosition())
					{
						min_i = i;
						max_i = start_i;

					}
					else
					{
						max_i = i;
						min_i = start_i;

					}

					

					while (temp_pixel == this_pixel)
					{
						
						ScalarTraceStorage *min_trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, min_i));
						ScalarTraceStorage *max_trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, max_i));
		
						if (trace->GetPosition() < min_trace->GetPosition())
						{
							min_i = i;
						}
						if (trace->GetPosition() > max_trace->GetPosition())
						{
							max_i = i;
						}

						stop_i = i;
						

						++i;
						if (i > lastTraceIndex)
						{
							break;
						}
						temp_pixel = (int)(timeToPixel * (TraceStorage::FindElement(dataHolder, i)->GetTraceTime() - startTime));
						trace = (ScalarTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
					}

					traceArray[start_index] = start_i; 
					traceMode[start_index] = StartDouble;

					traceArray[min_index] = min_i;
					traceMode[min_index] = MinTrace;
					
					traceArray[max_index] = max_i;
					traceMode[max_index] = MaxTrace;
					
					traceArray[stop_index] = stop_i;
					traceMode[stop_index] = EndDouble;

				}
			}

			traceArray[start_trace] = -1;
		}
	}
	else
	{
		traceArray[start_trace] = -1;
	}

	alreadyWorking = FALSE;

	return TRUE;

}

//##########################################################################
//#######################   ReceiverMessageTraceLine    
//##########################################################################

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

int ReceiverMessageTraceLine::GetTraceType()
{
	return CLabRatDoc::ReceiverMessageTraceType;
}

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

void
	ReceiverMessageTraceLine::DrawCurrentValue(int offset, Time timeOfValue)
{


	TraceLine::DrawCurrentValue(offset, timeOfValue);

	if(!traceMade)
	{
		return;
	}
	if(!on)
	{
		return;
	}

	MY_RGB black;
	black.red = 0; black.blue = 0; black.green = 0;
	MY_RGB light_grey;
	light_grey.red = 192; light_grey.blue = 192; light_grey.green = 192;
	MY_RGB white;
	white.red = 255; white.blue = 255; white.green = 255;


	Logical
		edge_flag = 0;

	int 
		message_priority = 0,
		class_ID = 0,
		message_ID = 0;


	int i = firstTraceIndex;

	Scalar value = 0.0f;

	while (i <= lastTraceIndex)
	{	
		Time current_time = TraceStorage::FindElement(dataHolder, i)->GetTraceTime();
		
		if (current_time > timeOfValue)
		{
			break;
		}
		else
		{
			ReceiverMessageTraceStorage *trace = (ReceiverMessageTraceStorage*)(TraceStorage::FindElement(dataHolder, i));
			value = trace->GetPosition();

			message_priority = trace->messagePriority;
			class_ID = trace->classID;
			message_ID = trace->messageID;
			edge_flag = trace->edgeFlag;

			++i;
		}
	}


	char value_text[100];

	if (edge_flag == 0)
	{
		strcpy(value_text, "-");
	}
	else if (drawMode == DrawPosition)
	{
		sprintf(value_text, "%f", value);
	}
	else if (drawMode == DrawID)
	{
		if (edge_flag == ReceiverMessageTraceStorage::messageQue)
		{
			sprintf(value_text, "Q %d %d::%d", message_priority, class_ID, message_ID);
		}
		else if (edge_flag == ReceiverMessageTraceStorage::messageDispatch)
		{
			sprintf(value_text, "D %d %d::%d", message_priority, class_ID, message_ID);
		}
	}
	else if (drawMode == DrawName)
	{

		ClassIDList *class_id_list = document->FindClass(class_ID);
		if (class_id_list != NULL)
		{
			CString class_name = class_id_list->entityName;
			CString message_name = ((CObjString *)class_id_list->messageList->GetAt(message_ID))->name;


			if (edge_flag == ReceiverMessageTraceStorage::messageQue)
			{
				sprintf(value_text, "Q %d %s::%s", message_priority, class_name, message_name);
			}
			else if (edge_flag == ReceiverMessageTraceStorage::messageDispatch)
			{
				sprintf(value_text, "D %d %s::%s", message_priority, class_name, message_name);
			}
		}
		else
		{
			if (edge_flag == ReceiverMessageTraceStorage::messageQue)
			{
				sprintf(value_text, "Q %d %d::%d", message_priority, class_ID, message_ID);
			}
			else if (edge_flag == ReceiverMessageTraceStorage::messageDispatch)
			{
				sprintf(value_text, "D %d %d::%d", message_priority, class_ID, message_ID);
			}
		}
	}


	int size = CalculateSize();

#if 0
	if (selected)
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, white);
	}
	else
#endif
	{
		myParent->DrawText(value_text, myParent->valueSize.left, offset+size-2, black);
	}
}