// InformerGraph.m
//

#import "InformerGraph.h"

@implementation InformerGraph

/////////////////////////////////////////////////////////////
// Initializes the view's instance variables.

- initFrame:(const NXRect *)frameRect
{
[super initFrame:frameRect];
[self setFlipped:YES];

currentX = 0;
MinY = MaxY = 0;
strcpy(title, "Untitled");
strcpy(numFormat, "%.0f");

myFont = [Font newFont:"Helvetica"  size:9.0];

return self;
}

/////////////////////////////////////////////////////////////
// Free method

- free
{
return [super free];
}

/////////////////////////////////////////////////////////////
// Drawing method

- drawSelf:(const NXRect *)rects :(int)rectCount
{
NXRect	theRect;
float	width, height;
char	tmpChar[64];
int		i;

[self getBounds:&theRect];
width = theRect.size.width;
height = theRect.size.height;

PSsetgray(NX_WHITE);
NXRectFill(&theRect);

PSsetgray(NX_DKGRAY);
[myFont set];

PSmoveto(2, 25);
if (isDelta)
	sprintf(tmpChar, "%s (D)", title);
else
	strcpy(tmpChar, title);
PSshow(tmpChar);

sprintf(tmpChar, numFormat, MaxY);
PSmoveto(2, 10);
PSshow(tmpChar);
sprintf(tmpChar, numFormat, MinY);
PSmoveto(2, height - 3);
PSshow(tmpChar);

PSsetgray(NX_BLACK);
PSsetlinewidth(1.0);
if (currentX > 0)
	{
	PSnewpath();
	PSmoveto(0, height - (((values[0] - MinY) / (MaxY - MinY)) * height));
	for (i = 0; i < currentX; i++)
		PSlineto((float)i, height - (((values[i] - MinY) / (MaxY - MinY)) * 
																	height));
	PSstroke();
	PSmoveto((float)currentX, height -
			(((values[currentX - 1] - MinY) / (MaxY - MinY)) * height) - 1);
	sprintf(tmpChar, numFormat, values[currentX - 1]);
	PSshow(tmpChar);
	}

return self;
}

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

- initMin:(float)theMin max:(float)theMax title:(char *)theTitle
												numFormat:(char *)theFormat
{
MinY = theMin;
MaxY = theMax;
if (MaxY == MinY)
	MaxY = MinY + 1;
currentX = 0;
strncpy(title, theTitle, MAXGRAPHTITLE - 1);
strncpy(numFormat, theFormat, 31);
[self display];

return self;
}

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

- addPoint:(float)thePoint
{
NXRect	theRect;
float	width, height;
int		i, scrollFactor;

isDelta = NO;
[self getBounds:&theRect];
width = theRect.size.width;
height = theRect.size.height;

if (thePoint > MaxY - (12 * (MaxY - MinY) / height))
	if (thePoint > 0)
		MaxY = thePoint * 1.2;
	else
		MaxY = thePoint * 0.8;

if (thePoint < MinY)
	if (thePoint > 0)
		MinY = thePoint * 0.8;
	else
		MinY = thePoint * 1.2;

values[currentX++] = thePoint;

if ((currentX >= MAXGRAPHVALUES) || (currentX >= (width - 25)))
	{
	scrollFactor = width / 5;
	for (i = 0; i < currentX; i++)
		values[i] = values[i + scrollFactor];
	currentX -= scrollFactor;
	}

[self display];

return self;
}

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

- addDeltaPoint:(float)thePoint
{
NXRect			theRect;
float			width, height;
int				i, scrollFactor;
float			newPoint;

isDelta = YES;
[self getBounds:&theRect];
width = theRect.size.width;
height = theRect.size.height;

if (currentX)
	newPoint = thePoint - formerPoint;
else
	newPoint = 0;

formerPoint = thePoint;

if (newPoint > MaxY - (12 * (MaxY - MinY) / height))
	if (newPoint > 0)
		MaxY = newPoint * 1.2;
	else
		MaxY = newPoint * 0.8;

if (newPoint < MinY)
	if (newPoint > 0)
		MinY = newPoint * 0.9;
	else
		MinY = newPoint * 1.1;

values[currentX++] = newPoint;

if ((currentX >= MAXGRAPHVALUES) || (currentX >= (width - 25)))
	{
	scrollFactor = width / 5;
	for (i = 0; i < (currentX - scrollFactor); i++)
		values[i] = values[i + scrollFactor];
	currentX -= scrollFactor;
	}

[self display];

return self;
}

@end
