#import "PAThumbWheel.h"
#import "PAThumbWheelCell.h"

static id TWCellClass = nil;

/******************************************************************************
	PAThumbWheelCell
	
PAThumbWheel offers the functionality of Slider plus the features that you would expect from a real thumbwheel (including 2 3/4 D Graphics!).

PAThumbWheel has a linear display mode and a radial display mode and offers the ability to assign a value to the visible region of the control as well as an absolute value that the ThumbWheel will either ignore, bound to or wrap around.

PAThumbWheel can also return relative values via its -relativeIntValue & -relativeFloatValue methods. A snap back option allows mouse loops to start from and return to a base value.

Copyright 1992, Jeff Martin. (jmartin@next.com 415-780-3833)
******************************************************************************/

@implementation PAThumbWheel

+ setCellClass:factoryId
{
    TWCellClass = factoryId;
    return self;
}

- (BOOL)acceptsFirstMouse {return YES;}

- initFrame:(const NXRect *)f
{
  [super initFrame:f];
  if(TWCellClass) [self setCell:[[TWCellClass alloc] init]];
  else [self setCell:[[PAThumbWheelCell alloc] init]];
  return self;
}

// Direction: vertical or horizontal
- (int)direction { return [cell direction]; }
- setDirection:(int)dir { [cell setDirection:dir]; return self; }
- takeDirectionFromMatrix:sender
{ [cell setDirection:[sender selectedTag]]; [self display]; return self; }
- (BOOL)isVertical { return [(PAThumbWheel *)cell isVertical]; }
- setVertical { [cell setVertical]; return self; }
- (BOOL)isHorizontal { return [cell isHorizontal]; }
- setHorizontal { [cell setHorizontal]; return self; }

// DisplayMode: radial or linear
- (int)displayMode { return [cell displayMode]; }
- setDisplayMode:(int)mode { [cell setDisplayMode:mode]; return self; }
- takeDisplayModeFromMatrix:sender
{ [cell setDisplayMode:[sender selectedTag]]; [self display]; return self; }
- toggleDisplayMode:sender
{ [cell setDisplayMode:![cell displayMode]]; [self display]; return self; }
- (BOOL)isRadial { return [cell isRadial]; }
- setRadial { [cell setRadial]; return self; }
- (BOOL)isLinear { return [cell isLinear]; }
- setLinear { [cell setLinear]; return self; }

// Visible min and max
- (float)visibleMax { return [cell visibleMax]; }
- setVisibleMax:(float)max { [cell setVisibleMax:max]; return self; }
- takeVisibleMaxFrom:sender
{ [cell setVisibleMax:[sender floatValue]]; [self display]; return self; }
- (float)visibleMin { return [cell visibleMin]; }
- setVisibleMin:(float)min { [cell setVisibleMin:min]; return self; }
- takeVisibleMinFrom:sender
{ [cell setVisibleMin:[sender floatValue]]; [self display]; return self; }
- (float)visibleRange { return [cell visibleRange]; }
- (float)middleValue { return [cell middleValue]; }

// Absolute mode: unbounded, bounded or wrapped
- (int)absoluteMode { return [cell absoluteMode]; }
- setAbsoluteMode:(int)mode { [cell setAbsoluteMode:mode]; return self; }
- takeAbsoluteModeFromMatrix:sender
{ [cell setAbsoluteMode:[sender selectedTag]]; [self display]; return self; }
- (BOOL)isUnbounded { return [cell isUnbounded]; }
- setUnbounded { [cell setUnbounded]; return self; }
- (BOOL)isBounded { return [cell isBounded]; }
- setBounded { [cell setBounded]; return self; }
- (BOOL)isWrapped { return [cell isWrapped]; }
- setWrapped { [cell setWrapped]; return self; }
- (float)absoluteMax { return [cell absoluteMax]; }
- setAbsoluteMax:(float)value { [cell setAbsoluteMax:value]; return self; }
- takeAbsoluteMaxFrom:sender
{ [cell setAbsoluteMax:[sender floatValue]]; [self display]; return self; }
- (float)absoluteMin { return [cell absoluteMin]; }
- setAbsoluteMin:(float)value { [cell setAbsoluteMin:value]; return self; }
- takeAbsoluteMinFrom:sender
{ [cell setAbsoluteMin:[sender floatValue]]; [self display]; return self; }
- (float)absoluteRange { return [cell absoluteRange]; }

// Relative Values
- (int)relativeIntValue { return [cell relativeIntValue]; }
- (float)relativeFloatValue { return [cell relativeFloatValue]; }
- resetRelativeValue { [cell resetRelativeValue]; return self; }

// Snap back characteristic
- (BOOL)snapsBack { return [cell snapsBack]; }
- setSnapsBack:(BOOL)flag { [cell setSnapsBack:flag]; return self; }
- takeSnapsBackFromSwitch:sender
{ [cell setSnapsBack:[sender state]]; [self display]; return self; }
- (float)snapBackValue { return [cell snapBackValue]; }
- setSnapBackValue:(float)val { [cell setSnapBackValue:val]; return self; }
- takeSnapBackValueFrom:sender
{ [cell setSnapBackValue:[sender floatValue]]; [self display]; return self; }

// Dash interval (set in degrees or points depending on displayMode)
- (float)dashInterval { return [cell dashInterval]; }
- setDashInterval:(float)val { [cell setDashInterval:val]; return self; }
- takeDashIntervalFrom:sender
{ [cell setDashInterval:[sender floatValue]]; [self display]; return self; }

// Showing the main dash
- (BOOL)showMainDash { return [cell showMainDash]; }
- setShowMainDash:(BOOL)flag { [cell setShowMainDash:flag]; return self; }
- takeShowMainDashFromSwitch:sender
{ [cell setShowMainDash:[sender state]]; [self display]; return self; }

// Color of the ThumbWheel
- (NXColor)color { return [cell color]; }
- setColor:(NXColor)color { [cell setColor:color]; return self; }
- takeColorFrom:sender { [self setColor:[sender color]]; return self; }

// tag and disabled
- takeTagFrom:sender { [self setTag:[sender intValue]]; return self; }
- takeDisabledFromSwitch:sender
{ [self setEnabled:![sender state]]; [self display]; return self; }

- (const char *)getInspectorClassName { return "PAThumbWheelInspector"; }

@end
