
/*---------------------------------------------------------------------------------------------------- 
   Implementation of the "DownhillLine" class.  See "uphillLine" for a little more documentation.
	 
	 HISTORY
	 
	 	22Mar93	DM	New
		
 ----------------------------------------------------------------------------------------------------*/

#import <dpsclient/wraps.h>
#import <math.h>

#import "DownhillLine.h"

#import "line.h"

@implementation DownhillLine

- drawSelf:(NXRect *)rects :(int)count;				// The classic NeXT method
{
 /*-----------------------------------------------------------------------------
	   A "downhill" line, going from the upper left of the box to the lower right.
	-----------------------------------------------------------------------------*/
	float	redComponent, greenComponent, blueComponent, alphaComponent;	// The components of the color
	NXColor	drawingColor;																								// either the enabled or disabled color
	float		angle, leg1, leg2;																					// utility trig things


		// Get the line grey and the width set, then start drawing things
	
	drawingColor = ([self isEnabled]) ? enabledColor : disabledColor;
	[self setFlipped:NO];																								// starts out flipped in buttons. 
																																			// fix that and conserve sanity
	
	NXConvertColorToRGBA(drawingColor, &redComponent, &greenComponent, &blueComponent, &alphaComponent);

			// Deal with the alpha component.  If none is specified, set it to 1.0 (opaque paint);
			// otherwise, respect what was set in the color.
		
	if(alphaComponent == NX_NOALPHA)
		PSsetalpha(1.0);
	 else
	 	PSsetalpha(alphaComponent);


	PSsetrgbcolor(redComponent, greenComponent, blueComponent);
	PSsetlinewidth(lineWidth);
	
			// Figure out the "start" and "end" points; don't want to go all the way to the edge, since
			// this screws up the arrows.
	
	angle = atan(bounds.size.height/bounds.size.width);
	leg1  = sin(angle) * lineWidth;
	leg2 	= cos(angle) * lineWidth;
	angle = (angle/(2 * M_PI)) * 360;								// Convert from radians
	
			// Draw arrows on end, if so desired.
	if(startArrow)
		{
			PSArrow(leg2, bounds.size.height - leg1, 180.0 - angle);					// Don't go quite all the way to the edges
			PSstroke();
		}
	
	if(endArrow)
		{
			PSArrow(bounds.size.width - leg2, leg1, 360 - angle);
			PSstroke();
		}

	PSnewpath();
	
		// Some munging around to get the arrows looking neat, if any
	
	if(startArrow)																											// Don't want square end butts screwing up my arrows
		PSmoveto(leg2, bounds.size.height - leg1);
	 else
		PSmoveto(0, bounds.size.height);
	
	if(endArrow)
		PSlineto(bounds.size.width - leg2, leg1);
	 else
	 	PSlineto(bounds.size.width, 0);
	
	PSstroke();
	
	return self;
}

- mouseDown:(NXEvent*)theEvent;								// Mousedown handling
{
	/*----------------------------------------------------------------------
	   See comments in "UphillLine.m"
	----------------------------------------------------------------------*/
	
	float 	diagonalAngle, mouseClickAngle;	//angle from x-axis, generally
  NXPoint	mousePoint;											//the click point, usually
  float		distance;												//distance to line
  	  
			// Convert from window coordinates to local view coordinates.
	
  mousePoint.x = theEvent->location.x; mousePoint.y = theEvent->location.y;
  [self convertPoint:&mousePoint fromView:nil];	
	
  mousePoint.x = mousePoint.x - bounds.origin.x;
  mousePoint.y = mousePoint.y - bounds.origin.y;  	
	mousePoint.y = bounds.size.height - mousePoint.y;

     	// find the angles and the difference between them
			
  diagonalAngle 	= atan(bounds.size.height/bounds.size.width);
  mouseClickAngle 	= atan(mousePoint.y/mousePoint.x);
  distance = sqrt(mousePoint.x*mousePoint.x + mousePoint.y*mousePoint.y)*
  sin(fabs(diagonalAngle - mouseClickAngle));
     
   if ((distance - (lineWidth/2.0) - HIT_TOLERANCE) <= 0.0)
       return [self performClick:self];
    else
       return [self passOnEvent:theEvent];

	 return self;						// compiler fodder
}       



@end
