
/* Generated by Interface Builder */

#import "EyeView.h"
#import "eye.h"

#import <stdlib.h>
#import <math.h>
#import <dpsclient/dpsclient.h>
#import <dpsclient/psops.h>
#import <appkit/Application.h>
#import <appkit/Window.h>
#import <appkit/defaults.h>

#define MAX_BALL_RAD	9.0
#define PUPIL_RAD	2.0
#define GAP		4.0
#define SQR(x)          ((x)*(x))

static void notifyTimer(DPSTimedEntry teNumber, double now, id self)
{
    [self drawBalls];
}


@implementation EyeView

- initFrame:(const NXRect *) frm;
{
    self = [super initFrame:frm];
    [self allocateGState];
    updateTime = atof(NXGetDefaultValue([NXApp appName],"EyeUpdateTime"));
    leftCenter.x  = bounds.size.width / 4;
    rightCenter.x = bounds.size.width * 3 / 4;
    leftCenter.y = rightCenter.y = bounds.size.height / 2;
    eyeball_init(PUPIL_RAD,MAX_BALL_RAD + GAP +1 ,leftCenter.x, leftCenter.y, rightCenter.x, rightCenter.y);
    return self;
}

- initializeEyes
{
    // draw the eye background
    [self lockFocus];
    eyebackground(bounds.size.width, bounds.size.height,leftCenter.x, leftCenter.y,
		  rightCenter.x, rightCenter.y, MAX_BALL_RAD + PUPIL_RAD + GAP);
    [self unlockFocus];
    [window flushWindow];
    NXPing();
    timedEntry = DPSAddTimedEntry(updateTime, (DPSTimedEntryProc) &notifyTimer, self, NX_BASETHRESHOLD);
    
    return self;
}

- free
{
    DPSRemoveTimedEntry(timedEntry);
    return [super free];
}

- setUpdateTime:(double)value
{
    updateTime = value;
    DPSRemoveTimedEntry(timedEntry);
    timedEntry = DPSAddTimedEntry(updateTime, (DPSTimedEntryProc) &notifyTimer, self, NX_BASETHRESHOLD);
    return self;
}

- (double)updateTime
{
    return updateTime;
}

- stopTimer
{
    DPSRemoveTimedEntry(timedEntry);
    return self;
}

- startTimer
{
    timedEntry = DPSAddTimedEntry(updateTime, (DPSTimedEntryProc) &notifyTimer, self, NX_BASETHRESHOLD);
    return self;
}

- drawBalls
{
    mouseTemp = mouseLoc;
    [window getMouseLocation: &mouseLoc];
    [self convertPoint: &mouseLoc fromView: nil];
    if (mouseLoc.x == mouseTemp.x && mouseLoc.y == mouseTemp.y) 
	return self;

    mag = sqrt(SQR(mouseLoc.x - leftCenter.x) + SQR(mouseLoc.y - leftCenter.y));
    if (mag < MAX_BALL_RAD) {
    	leftBall.x = mouseLoc.x;
    	leftBall.y = mouseLoc.y;
    } else {
    	leftBall.x = MAX_BALL_RAD * (mouseLoc.x - leftCenter.x) / mag + leftCenter.x ;
    	leftBall.y = MAX_BALL_RAD * (mouseLoc.y - leftCenter.y) / mag + leftCenter.y ;
    }
    mag = sqrt(SQR(mouseLoc.x - rightCenter.x) + SQR(mouseLoc.y - rightCenter.y));
    if (mag < MAX_BALL_RAD) {
    	rightBall.x = mouseLoc.x;
    	rightBall.y = mouseLoc.y;
    } else {
    	rightBall.x = MAX_BALL_RAD * (mouseLoc.x - rightCenter.x) / mag + rightCenter.x;
    	rightBall.y = MAX_BALL_RAD * (mouseLoc.y - rightCenter.y) / mag + rightCenter.y;
    }
    
    [self lockFocus];
    eyeball(leftBall.x, leftBall.y, rightBall.x, rightBall.y);
    [window flushWindow];
    [self unlockFocus];
    NXPing();
    return self;
}

@end
