
/* Generated by Interface Builder */

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

@implementation Battery

- init
{
    [super init];
    battery = self;
    return self;
}

- read:(NXTypedStream *)stream
{
    [super read:stream];
    NXReadTypes(stream,"ffffcccd",&efficiency,&mass,&max,&peakDraw,&plotAmps,&plotCharge,&plotVolts,&present);
    NXReadArray(stream,"f",6,ampCoefficients);
    NXReadArray(stream,"f",6,voltCoefficients);
    return self;
}

- write:(NXTypedStream *)stream
{
    [super write:stream];
    NXWriteTypes(stream,"ffffcccd",&efficiency,&mass,&max,&peakDraw,&plotAmps,&plotCharge,&plotVolts,&present);
    NXWriteArray(stream,"f",6,ampCoefficients);
    NXWriteArray(stream,"f",6,voltCoefficients);
    return self;
}

- (float *)ampCoefficients
{
    return ampCoefficients;
}

- setAmpCoefficients:(float *)theCoefficients
{
int i;

    for ( i = 0 ; i < 6 ; i++ )
        ampCoefficients[i] = theCoefficients[i];
    return self;
}

- (float)efficiency
{
    return efficiency;
}

- setEfficiency:(float)aNumber
{
    efficiency = aNumber;
    return self;
}

- (float)mass
{
    return mass;
}

- setMass:(float)aNumber
{
    mass = aNumber;
    return self;
}

- (float)max
{
    return max;
}

- setMax:(float)aNumber
{
    max = aNumber;
    return self;
}

- (float)peakDraw
{
    return peakDraw;
}

- setPeakDraw:(float)aNumber
{
    peakDraw = aNumber;
    return self;
}

- (BOOL)plotAmps
{
    return plotAmps;
}

- setPlotAmps:(BOOL)flag
{
    plotAmps = flag;
    return self;
}

- (BOOL)plotCharge
{
    return plotCharge;
}

- setPlotCharge:(BOOL)flag
{
    plotCharge = flag;
    return self;
}

- (BOOL)plotVolts
{
    return plotVolts;
}

- setPlotVolts:(BOOL)flag
{
    plotVolts = flag;
    return self;
}

- (double)present
{
    return present;
}

- setPresent:(double)aNumber
{
    present = aNumber;
    return self;
}

- (float *)voltCoefficients
{
    return voltCoefficients;
}

- setVoltCoefficients:(float *)theCoefficients
{
int i;

    for ( i = 0 ; i < 6 ; i++ )
        voltCoefficients[i] = theCoefficients[i];
    return self;
}

/******************************************************************************************************************************
 *    This is the actual part that does the work.  It's not very complicated.  Note: It's a lot better to have very separate  *
 *    cases for positive, zero, and negative power.  The code is less efficient, but there is much less confusion this way.   *
 *    Eventually, the other objects should be rewritten in this fashion.  Sorry I didn't think of this earlier.               *
 ******************************************************************************************************************************/
- (float)powerRequested:(float)power forTime:(float)time
{
float volts;
float amps;
float ampsAvailable;

    if ( power > 0 )
        {
        volts = evaluatePolynomial(voltCoefficients,6,present);		// Get the maximum voltage available
        ampsAvailable = evaluatePolynomial(ampCoefficients,6,present);	// Get the maximum curretn available

        amps = power / volts;						// Calculate the maximum current needed
        amps = MIN(amps,ampsAvailable);					// Take to lower one

        present -= ( amps * volts * time / efficiency ) / 3600000.0;	// Update the current charge level

        return (amps * volts);
        }
    else if ( power < 0 )
        {
        present -= ( power * time * efficiency ) / 3600000;		// Since the power is negative, we multiply by the 
        return power;							// Battery efficiency so that we recharge less than we
        }								// get. Remember to convert J to kWh!
    else if ( power == 0 )
        {
        return 0;
        }
    return 0;
}

- getSetForRun
{
    startingLevel = present;
    return self;
}

- finishedRun
{
    present = startingLevel;
    return self;
}

- report:(NXStream *)stream
{
    NXPrintf(stream,"Battery:\n");
    NXPrintf(stream,"  Energy Used:%fkWh\n",startingLevel-present);
    return self;
}

@end










