/***********************************************************************\
Common class for displaying a circular progress indicator in all Convert programs
Copyright (C) 1993 David John Burrowes

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

The author, David John Burrowes, can be reached at:
	davidjohn@kira.net.netcom.com
	David John Burrowes
	1926 Ivy #10
	San Mateo, CA 94403-1367
\***********************************************************************/

#import "ProgressIndicator.h"
#import "ProgressInd.h"
@implementation ProgressIndicator
// #import <dpsclient/psops.h>
#import <dpsclient/wraps.h>	// for PSsetgray()
#import <appkit/graphics.h>	// for NX_BLACK and _WHITE

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		drawSelf::
//	Parameters:	the rectangles to draw in, and a count of how many there are.
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		This redraws the indicator object.  Because of the simplicity of the object,
//		we ignore the rects and draw the whole thing every time.
//	Bugs:
//		I can't remember if I must manually flush the image if we're buffered or not...
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

- drawSelf:(const NXRect *)rects :(int)rectCount
{
	NXRect	theFrame;
	NXRect *myFrame = &theFrame;
	Real		height, width, radius, percent;
	[self getBounds: myFrame];
	//
	//	Fill our rectangle with grey
	//
	PSsetgray(NX_LTGRAY);
	NXRectFill(myFrame);
	//
	//	Now, if needed, draw the indicator.
	//
	if (active == YES)
	{
		percent =  CurrentValue / numUnits;
		if (percent < 0 )	// One of the two has the wrong sign... negative progress, essentially
			percent = 0;
		if (percent > 1)
			percent = 1;
		//
		//	Calculate smaller dimension use as a radius
		//
		height = NX_HEIGHT(myFrame);
		width = NX_WIDTH(myFrame);
		if (height > width)
			radius = width / 2;
		else
			radius = height / 2;
		DrawIndicator(360*percent, NX_MIDX(myFrame) ,NX_MIDY(myFrame), radius);
	}
	return self;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		init
//	Parameters:	none
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		This merely initalizes the instance variables, as you would expect.
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- init
{
	[super init];
	
	active = NO;
	numUnits = 0;
	CurrentValue = 0;
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		ActivateWithGoal
//	Parameters:	A number that constitutes the 'finish line'.
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		This does several things.  First, it makes us active, which means we will
//		now draw ourself.  Second, we set up the specified count as the number that
//		constitutes our goal (That is, reaching count is 100% done).  We establish
//		the current progression towards that goal as 0.  Note that the goal can be
//		negative if desired.  Starting point is always 0 though.
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- ActivateWithGoal: (Real) count
{
	active = YES;
	numUnits = count;
	CurrentValue = 0;
	[window display];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		Deactivate
//	Parameters:	none
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		After clearing the internal counter and current value, and setting the active
//		flag to false, this will cause this indicator to be cleared.
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- Deactivate
{
	active = NO;
	numUnits = 0;
	CurrentValue = 0;
	[window display];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		IncrementBy:
//	Parameters:	A value to increment our current value by
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		Unsurprisingly, we take our argument, and increment our current value
//		by it, and then redraw.  This will cause the arc on the screen to fill a bit more
//		of the circle.  (or if the units are the reverse sign of the gooal, cause it to back up)
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- IncrementBy: (Real) units
{
	CurrentValue += units;
	[window display];
	return self;
}


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Method:		SetTo:
//	Parameters:	A new value to set the indicator to.
//	Returns: 	self
//	Stores:		n/a
//	Description:
//		This discards whatever setting this object had before, and sets the current
//		value to the specified setting.  The indicator is then redrawn to reflect this
//		change.
//	Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- SetTo: (Real) units;
{
	CurrentValue = units;
	[window display];
	return self;
}

@end
