
/*
	MiscGaugeView.m
  
  	This object is included in the MiscKit by permission from the author
  	and its use is governed by the MiscKit license, found in the file
  	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
  	for a list of all applicable permissions and restrictions.
*/

#import <AppKit/AppKit.h>
#import "MiscGaugeCell.h"
#import "MiscGaugeView.h"

// The cell our Control will display.
static Class myCellClass;


@implementation MiscGaugeView 

/*"
	This class is basically a cover for a MiscGaugeCell which does pretty 
	much all the work when we give it some View real estate to draw in. See the 	
	MiscGaugeCell class for more information on the inner workings of the 
	gauge. Even the documentation below was basically cut and pasted from the 	
	MiscGaugeCell docs.
"*/


+ (void) initialize
/*"
   Sets our cell class to be MiscGaugeCell.
"*/
{
    if (self == [MiscGaugeView class]) {
		// By default use the MiscGaugeCell cell.
        [self setCellClass:[MiscGaugeCell class]];
    }
}


+ (Class) cellClass
/*"
   Returns the class of the cell we will use. It should be a
   subclass of MiscGaugeCell or the class itself (the default).
"*/
{
    return myCellClass;
}


+ (void) setCellClass:(Class)aClass
/*"
   Sets aClass to be the cell we'll use as our gauge cell. It
   should be a subclass of MiscGaugeCell.
"*/
{
	myCellClass = aClass;
}


- (id) initWithFrame:(NSRect)frameRect
/*"
   Just calls our designated initializer (right below) with some
   reasonable values.
"*/
{
    [self initWithFrame:frameRect min:0.0 max:100.0 startAngle:215.0 range:250.0
       tickInterval:10]; 
	return self;
}


- (id) initWithFrame:(NSRect)frameRect min:(double)min max:(double)max
          startAngle:(float)start range:(float)range tickInterval:(int)interval
/*"
   This our designated initializer. Sets all the ivars from parameters
   above. The default title font is also set to Helvetica 10pt.
   Returns self.
"*/
{
    BOOL error = ([super initWithFrame:frameRect] == nil);

    if (!error) {
        // Set ourselves to use our gaugecell.
        [self setCell: [[[myCellClass alloc] init] autorelease]];

        [self setStartAngle:start];
        [self setAngleRange:range];
        [self setTickInterval:interval];
        [self setMinValue:min];
        [self setMaxValue:max];
        [self setFloatValue:min];
        [self setTitleFont:[NSFont fontWithName:@"Helvetica" size:10]];
    }
    
	return error ? nil : self;
}


- (double) maxValue
/*"
   Returns the maximum value of the gauge.
"*/
{
    return [[self cell] maxValue];
}


- (void) setMaxValue:(double)max
/*"
   Sets a new maximum value for the gauge. If the new maximum value
   happens to be lower than the current minimum, the minimum value
   is adjusted to be one less than max. If the value of the gauge
   (as returned by #{floatValue}) is now larger than the gauge's
   new maximum it is also changed to equal max.
"*/
{
    // Don't redraw if the new max is the same as the old.
    if (max != [[self cell] maxValue]) {
        [[self cell] setMaxValue: max];
        [self setNeedsDisplay:YES];
    }
}


- (double) minValue
/*"
   Returns the minimum value of the gauge.
"*/
{
    return [[self cell] minValue];
}


- (void) setMinValue:(double)min 
/*"
   Sets a new minimum value for the gauge. If the new minimum value
   happens to be higher than the current maximum, the maximum value
   is adjusted to be one greater than min. If the value of the gauge
   (as returned by floatValue) is now smaller than the gauge's new
   minimum it is also changed to equal min.
"*/
{ 
	// Don't redraw if the new min is the same as the old.
    if (min != [[self cell] maxValue]) {
		[[self cell] setMinValue: min]; 
		[self setNeedsDisplay:YES];
	}
}


- (float) startAngle
/*"
   Returns the gauge's start angle (where the minimum value is located).
   See the #setStartAngle: method for more information.
"*/
{
    return [[self cell] startAngle];
}


- (void) setStartAngle:(float)newValue
/*"
   Sets the angle, in degrees, where the minimum value of the gauge
   will appear. Zero degrees is due east, with increasing numbers
   moving the start counter-clockwise. The newValue should be between
   0 and 360. If not, it will be adjusted so it is.
"*/
{
    if (newValue != [[self cell] startAngle]) {
        [[self cell] setStartAngle:newValue];
        [self setNeedsDisplay:YES];
     }
}


- (float) angleRange
/*"
   Returns the sweep of the hand from minimum to maximum value,
   starting at startAngle. This will not be less than 0 or more
   than 360 degrees.
"*/
{
    return [[self cell] angleRange];
}


- (void)setAngleRange:(float)newValue
/*"
   Sets the span, in degrees, from the gauge's minimum to the maximum.
   The span starts at %startAngle and continues clockwise. if newValue is
   less than 0 or greater then 360, it will be adjusted
   (set to either 0 or 360, respectively) so it is within a meaningful range.
"*/
{
    if (newValue != [[self cell] angleRange]) {
        [[self cell] setAngleRange:newValue];
        [self setNeedsDisplay:YES];
     }
}


- (int) tickInterval
/*"
   Returns the current spacing of the tick marks on the gauge.
"*/
{
    return [[self cell] tickInterval];
}


- (void) setTickInterval:(int)newValue
/*"
   Sets the interval that the gauge face's tick marks should be
   drawn (including the numbers). For example, if you had a minimum
   value of 10.0 and a maximum of 100.0, then a tick interval of 10
   would probably be around right. A current limitation is that the
   tick interval cannot be less than 1. This will be fixed in a
   coming release.
"*/
{
    if (newValue != [ [self cell] tickInterval]) {
        [[self cell] setTickInterval:newValue];
        [self setNeedsDisplay:YES];
     }
}


- (float) tickRatio
/*"
   Returns the radius of the tick marks in relation to the gauge's radius.
   This value will be between 0.0 (no tick marks) and 1.0 (on the very edge
   of the gauge face.                                                        .
"*/
{
    return [[self cell] tickRatio];
}


- (void) setTickRatio:(float)newRatio
/*"
   Sets the tick mark's radius in ratio to the gauge face's radius.
   Usually this is adjusted if either the numbers or the gauge's title
   overlap the tick marks.
"*/
{
    if (newRatio != [ [self cell] tickRatio]) {
        [[self cell] setTickRatio:newRatio];
        [self setNeedsDisplay:YES];
     }
}


- (float) handRatio
/*"
   Returns the ratio of the hand length to the radius of the face.
   For reference, a value of  0.5 would mean the length of the hand
   was half of the radius of the gauge face.
"*/
{
    return [[self cell] handRatio];
}


- (void) setHandRatio:(float)newRatio
/*"
   Sets the hand length in ratio to the gauge's radius. A value of 0.5
   would draw a hand with a length half of the gauge's radius.  The value
   must be between 0.2 and 0.9. If it is either larger or smaller, the new
   ratio will be set to either 0.2 or 0.9 respectively.
"*/
{
    [[self cell] setHandRatio:newRatio];
    [self updateCellInside:[self cell]];
}


- (NSColor*) gaugeColor
/*"
   Returns the current color of the gauge face.
"*/
{ 	
    return [[self cell] gaugeColor];
}


- (void) setGaugeColor:(NSColor*)color
/*"
   Sets the color of the gauge face. I've found that pale
   colors are not a good choice.
"*/
{
    if (![color isEqual:[self gaugeColor]]) {
        [[self cell] setGaugeColor:color];
        [self setNeedsDisplay:YES];
     }
}


- (NSColor*) textColor
/*"
   Returns the color that the text and gauge hand are drawn in.
"*/
{
    return [[self cell] textColor];
}


- (void) setTextColor:(NSColor*)color
/*"
    Sets the color of the text and gauge hand.
"*/
{
    if (![color isEqual:[self textColor]]) {
		[[self cell] setTextColor: color];
		[self setNeedsDisplay:YES];
	 }
}


- (NSFont*) titleFont
/*"
   Returns the font that we'll use to draw our title.
"*/
{
    return [[self cell] titleFont];
}


- (void) setTitleFont:(NSFont*)newFont
/*"
   Sets the font for the gauge's title. No matter if this view is
   flipped or not, newFont should have an NX_IDENTITYMATRIX matrix.
"*/
{
    [[self cell] setTitleFont:newFont];
    [self setNeedsDisplay:YES];
}


- (NSString*) title
/*"
   Returns the gauge's current title.
"*/
{
    return [[self cell] title];
}


- (void) setTitle:(NSString*)newTitle
/*"
   Sets the gauge's title. A value of nil will remove the
   existing title.
"*/
{
    [[self cell] setTitle:newTitle];
    [self setNeedsDisplay:YES];
}


- (NSTitlePosition) titlePosition
/*"
   Returns the current position of the title even if there is no
   current title. Either NSAtTop or NSAtBottom will be returned.
"*/
{
    return [[self cell] titlePosition];
}


- (void) setTitlePosition:(NSTitlePosition)newPos
/*"
   Sets the position of the title. Currently the only valid positions
   are NSAtTop and NSAtBottom.
"*/
{
	// Valid positions are NX_ATTOP and NX_ATBOTTOM.
    if (newPos != [self titlePosition]) {
		[[self cell] setTitlePosition: newPos];
		[self setNeedsDisplay:YES];
	 }
}

@end

