
/* Generated by Interface Builder */

#import "Car_main.h"
#import "Road.h"
#import "DataView.h"
#import <streams/streams.h>
#import <appkit/nextstd.h>

@implementation Road

- init
{
    [super init];
    road = self;

    data = [[Storage alloc] initCount:0
		            elementSize:sizeof(struct plotData)
                            description:PLOTDATA_DESCRIPTION];
    return self;
}

- data
{
    return data;
}

- (float)temperature
{
    return temperature;
}

- setTemperature:(float)aNumber
{
    temperature = aNumber;
    return self;
}

- (float)windSpeed
{
    return windSpeed;
}

- setWindSpeed:(float)aNumber
{
    windSpeed = aNumber;
    return self;
}

- loadRoadFromStream:(NXStream *)stream
{
struct plotData point;
float length;
float slope;

    [data empty];
    point.x = 0;
    point.y = 0;
    [data addElement:&point];

    NXScanf(stream,"%f\n%f\n",&temperature,&windSpeed);
    while ( !NXAtEOS(stream) )
        {
        NXScanf(stream,"%f,%f\n",&length,&slope);
        point.x = point.x + length;
        point.y = point.y + slope * length;
        [data addElement:&point];
        }
    return self;
}

- (float)slope
{
float slope;
struct plotData *points;
int count;
int after;
int before;

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

    if ( count == 0 )							// If there is no road file loaded, return 0 slope
        return 0;

    if ( currentPosition > points[count-1].x )				// If there is no more data, return 0 slope
        return 0;
    
    for ( after = 0 ; points[after].x < currentPosition ; after++ );	// Look for a point that is >= the current position.
   
    if ( points[after].x == currentPosition )				// 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 >= currentPosition ; before-- );
    before = MAX(before,0);						// Check to see that we don't go beyond the data.

    slope = ( points[after].y - points[before].y ) / ( points[after].x - points[before].x );

    return slope;
}

- reset
{
    currentPosition = 0;
    return self;
}

- advance:(float)time atSpeed:(float)velocity
{
    currentPosition += time * velocity;
    return self;
}

- (float)distance
{
    return currentPosition;
}

- report:(NXStream *)stream
{
    NXPrintf(stream,"Environment:\n");
    NXPrintf(stream,"  Distance Travelled:%fkm\n",currentPosition/1000);
    return self;
}

@end
