
/* Generated by Interface Builder */

#import <objc/Storage.h>
#import "Car_main.h"
#import "Cycle.h"
#import "DataView.h"
#import <appkit/nextstd.h>

@implementation Cycle

- init
{
    [super init];
    cycle = self;
    timeStep = 1;
    return self;
}

- data
{
    return data;
}

- loadCycleFromStream:(NXStream *)stream
{
struct plotData point;

    if ( !data )
        data = [[Storage alloc] initCount:0
			        elementSize:sizeof(struct plotData)
                                description:PLOTDATA_DESCRIPTION];
    else
        [data empty];
    while ( !NXAtEOS(stream) )
        {
        NXScanf(stream,"%f,%f\n",&point.x,&point.y);
        [data addElement:&point];
        }
    return self;
}

- (float)end
{
    return end;
}

- setEnd:(float)aNumber
{
    end = MIN(aNumber,length);
    return self;
}

- (float)length
{
    return length;
}

- setLength:(float)aNumber
{
    length = aNumber;
    return self;
}

- (float)start
{
    return start;
}

- setStart:(float)aNumber
{
    start = MAX(aNumber,0);
    return self;
}

- reset
{
    presentTime = start;
    return self;
}

- getNextVelocity:(float *)velocity andAcceleration:(float *)acceleration
{
struct plotData *points;
int after;
int before;
int count;

    count = [data count];
    points = (struct plotData *)data->dataPtr;    

    if ( presentTime > points[count-1].x || presentTime > end )	// Signal the end of the cycle if there is no more data.
        return nil;						// or if we have reached the end.

    for ( after = 0 ; points[after].x < presentTime ; after++ );

    if ( points[after].x == presentTime )			// We want a middle derivative
        after = after++;

    after = MIN(after,count-1);					// Check to see that we don't go beyond the data

    for ( before = after -1 ; before >= 0 && points[before].x >= presentTime ; before-- );

    before = MAX(before,0);					// Check to see that we don't go beyond the data.
      
    *acceleration = ( points[after].y - points[before].y ) / ( points[after].x - points[before].x );
    
    *velocity = points[before].y + ( presentTime - points[before].x ) * *acceleration;

    lastTime = presentTime;
    presentTime += 1.0;						//Advance the current state
    return self;
}

- (float)lastTime
{
    return lastTime;
}

- (float)timeStep;
{
    return timeStep;
}

@end

