
/* Generated by Interface Builder */

#import <rpcsvc/bootparam.h>
#import <appkit/Button.h>
#import <appkit/Matrix.h>
#import <appkit/Form.h>
#import <appkit/Panel.h>
#import <appkit/Box.h>
#import <strings.h>
#import "Car_main.h"
#import "Inspector.h"
#import "Road.h"
#import "Car.h"
#import "Controller.h"
#import "Transmission.h"
#import "Engine.h"
#import "GasTank.h"
#import "Motor.h"
#import "Battery.h"
#import "Wheels.h"
#import "Cycle.h"
#import "AppDelegate.h"
#import "DataView.h"

static char windowTitles[10][MAX_PATH_LEN] = {"Environment Inspector",
                                               "Car Inspector",
                                               "Controller Inspector",
                                               "Transmission Inspector",
                                               "Engine Inspector",
                                               "Gas Tank Inspector",
                                               "Motor Inspector",
                                               "Battery Inspector",
                                               "Wheel Inspector",
                                               "Cycle Inspector"};
@implementation Inspector

// These are just some workarounds to a simple problem.  The variables from the nib file have not been initialized yet.

- init
{
   inspector = self;
   return self;
}

- setRoadBox:anObject;
{
    roadBox = anObject;
    boxList[0] = anObject;
    return self;
}

- OKRoadBox:sender
{
    [road setTemperature:[roadTemperature floatValue]];
    [road setWindSpeed:[roadWindSpeed floatValue]];
    return self;
}

- revertRoadBox:sender
{   
    [roadTemperature setFloatValue:[road temperature]];
    [roadWindSpeed setFloatValue:[road windSpeed]];
    return self;
}

- loadRoad:sender
{
char *filename;

    filename = [appDelegate openFileType:"environment"];
    [self updateRoadGraph:filename];
    return self;
}

- updateRoadGraph:(const char *)filename
{
    strcpy(windowTitles[0],filename);
    [roadGraph setData:[road data]];
    [inspectorPanel setTitleAsFilename:windowTitles[0]];
    [self OKCycleBox:self];
    [roadLength setFloatValue:[roadGraph xmax]];
    [inspectorPanel display];
    return self;
}

- setCarBox:anObject;
{
    carBox = anObject;
    boxList[1] = anObject;
    return self;
}

- OKCarBox:sender
{
    [car setDragCoefficient:[carDragCoefficient floatValue]];
    [car setFrontalArea:[carFrontalArea floatValue]];
    [car setMass:[carMass floatValue]];
    [car setPlotAcceleration:[carPlotAcceleration state]];
    [car setTestMode:[carTestMode selectedRow]];
    return self;
}

- revertCarBox:sender
{
    [carDragCoefficient setFloatValue:[car dragCoefficient]];
    [carFrontalArea setFloatValue:[car frontalArea]];
    [carMass setFloatValue:[car mass]];
    [carPlotAcceleration setState:[car plotAcceleration]];
    [carTestMode selectCellAt:[car testMode] :0];
    return self;
}

- updateCarBox:(const char *)filename
{
    strcpy(windowTitles[1],filename);
    [inspectorPanel setTitleAsFilename:windowTitles[1]];
    [inspectorPanel display];
    return self;
}

- setControllerBox:anObject;
{
    controllerBox = anObject;
    boxList[2] = anObject;
    return self;
}

- OKControllerBox:sender
{
    [controller setMass:[controllerMass floatValue]];
    [controller setShiftCeiling:[controllerShiftCeiling floatValue]];
    [controller setShiftFloor:[controllerShiftFloor floatValue]];
    return self;
}

- revertControllerBox:sender
{
    [controllerMass setFloatValue:[controller mass]];
    [controllerShiftCeiling setFloatValue:[controller shiftCeiling]];
    [controllerShiftFloor setFloatValue:[controller shiftFloor]];
    return self;
}

- setTransmissionBox:anObject;
{
    transmissionBox = anObject;
    boxList[3] = anObject;
    return self;
}

- OKTransmissionBox:sender
{
float gearRatios[5];
float shiftPoints[4];
int i;

    [transmission setCurrentGear:[transmissionCurrentGear intValue]];
    [transmission setEfficiency:[transmissionEfficiency floatValue]];
    [transmission setFinalDriveRatio:[transmissionFinalDriveRatio floatValue]];
    for ( i = 0 ; i < 5 ; i++ )
        gearRatios[i] = [transmissionGearRatios floatValueAt:i];
    [transmission setGearRatios:gearRatios];
    [transmission setMass:[transmissionMass floatValue]];
    [transmission setShiftLag:[transmissionShiftLag floatValue]];
    for ( i = 0 ; i < 4 ; i++ )
        shiftPoints[i] = [transmissionShiftPoints floatValueAt:i];
    [transmission setShiftPoints:shiftPoints];
    return self;
}

- revertTransmissionBox:sender
{
float *gearRatios;
float *shiftPoints;
int i;

    [transmissionCurrentGear setIntValue:[transmission currentGear]];
    [transmissionEfficiency setFloatValue:[transmission efficiency]];
    [transmissionFinalDriveRatio setFloatValue:[transmission finalDriveRatio]];
    gearRatios = [transmission gearRatios];
    for ( i = 0 ; i < 5 ; i++ )
        [transmissionGearRatios setFloatValue:gearRatios[i] at:i];
    [transmissionMass setFloatValue:[transmission mass]];
    [transmissionShiftLag setFloatValue:[transmission shiftLag]];
    shiftPoints = [transmission shiftPoints];
    for ( i = 0 ; i < 4 ; i++ )
        [transmissionShiftPoints setFloatValue:shiftPoints[i] at:i];
    return self;
}

- setEngineBox:anObject;
{
    engineBox = anObject;
    boxList[4] = anObject;
    return self;
}

- OKEngineBox:sender
{
float coefficients[6];
int i; 
float redline;
    
    redline = [engineRedline floatValue];

    for ( i = 0 ; i < 6 ; i++ )
        coefficients[i] = [engineCoefficients floatValueAt:i];
    [engine setCoefficients:coefficients];
    [engine setEfficiency:[engineEfficiency floatValue]];
    [engine setMass:[engineMass floatValue]];
    [engine setRedline:redline];
    [engine setStallSpeed:[engineStallSpeed floatValue]];
    [engine setStartLag:[engineStartLag floatValue]];
    [engineGraph setPlotMode:CURVE_ONLY];
    [engineGraph setCurveFromArray:coefficients count:6];
    [engineGraph rescaleForCurveWithRange:0 :redline checkInterval:redline/100];
    [inspectorPanel display];    
    return self;
}

- revertEngineBox:sender
{
float *coefficients;
int i;
float redline;

    redline = [engine redline];

    coefficients = [engine coefficients];
    for ( i = 0 ; i < 6 ; i++ )
        [engineCoefficients setFloatValue:coefficients[i] at:i];
    [engineEfficiency setFloatValue:[engine efficiency]];
    [engineMass setFloatValue:[engine mass]];
    [engineRedline setFloatValue:redline];
    [engineStallSpeed setFloatValue:[engine stallSpeed]];
    [engineStartLag setFloatValue:[engine startLag]];
    [engineGraph setPlotMode:CURVE_ONLY];
    [engineGraph setCurveFromArray:coefficients count:6];
    [engineGraph rescaleForCurveWithRange:0 :redline checkInterval:redline/100];
    [inspectorPanel display];
    return self;
}

- setGasTankBox:anObject;
{
    gasTankBox = anObject;
    boxList[5] = anObject;
    return self;
}

- OKGasTankBox:sender
{
    [gasTank setCurrent:[gasTankCurrent doubleValue]];
    [gasTank setEnergyDensity:[gasTankEnergyDensity floatValue]];
    [gasTank setFuelDensity:[gasTankFuelDensity floatValue]];
    [gasTank setMass:[gasTankMass floatValue]];
    [gasTank setMax:[gasTankMax floatValue]];    
    return self;
}

- revertGasTankBox:sender
{
    [gasTankCurrent setDoubleValue:[gasTank current]];
    [gasTankEnergyDensity setFloatValue:[gasTank energyDensity]];
    [gasTankFuelDensity setFloatValue:[gasTank fuelDensity]];
    [gasTankMass setFloatValue:[gasTank mass]];
    [gasTankMax setFloatValue:[gasTank max]];
    return self;
}

- setMotorBox:anObject;
{
    motorBox = anObject;
    boxList[6] = anObject;
    return self;
}

- OKMotorBox:sender
{
float lowEndCoefficients[6];
float highEndCoefficients[6];
int i;
float max;

    max = [motorMax floatValue];

    [motor setCrossover:[motorCrossover floatValue]];
    [motor setEfficiency:[motorEfficiency floatValue]];
    for ( i = 0 ; i < 6 ; i++ )
        lowEndCoefficients[i] = [motorLowCoefficients floatValueAt:i];
    [motor setLowCoefficients:lowEndCoefficients];
    for ( i = 0 ; i < 6 ; i++ )
        highEndCoefficients[i] = [motorHighCoefficients floatValueAt:i];
    [motor setHighCoefficients:highEndCoefficients];
    [motor setMass:[motorMass floatValue]];
    [motor setMax:max];
    [motor setRegenerationEfficiency:[motorRegenerationEfficiency floatValue]];

    [motorHighEndGraph setPlotMode:CURVE_ONLY];
    [motorHighEndGraph setCurveFromArray:highEndCoefficients count:6];
    [motorHighEndGraph rescaleForCurveWithRange:0 :max checkInterval:max/100];
    
    [motorLowEndGraph setPlotMode:CURVE_ONLY];
    [motorLowEndGraph setCurveFromArray:lowEndCoefficients count:6];
    [motorLowEndGraph rescaleForCurveWithRange:0 :max checkInterval:max/100];

    [inspectorPanel display];
    return self;
}

- revertMotorBox:sender
{
float *lowEndCoefficients;
float *highEndCoefficients;
int i;
float max;

    max = [motor max];

    [motorCrossover setFloatValue:[motor crossover]];
    [motorEfficiency setFloatValue:[motor efficiency]];
    lowEndCoefficients = [motor lowCoefficients];
    for ( i = 0 ; i < 6 ; i++ )
        [motorLowCoefficients setFloatValue:lowEndCoefficients[i] at:i];
    highEndCoefficients = [motor highCoefficients];
    for ( i = 0 ; i < 6 ; i++ )
        [motorHighCoefficients setFloatValue:highEndCoefficients[i] at:i];
    [motorMass setFloatValue:[motor mass]];
    [motorMax setFloatValue:max];
    [motorRegenerationEfficiency setFloatValue:[motor regenerationEfficiency]];

    [motorHighEndGraph setPlotMode:CURVE_ONLY];
    [motorHighEndGraph setCurveFromArray:highEndCoefficients count:6];
    [motorHighEndGraph rescaleForCurveWithRange:0 :max checkInterval:max/100];
    
    [motorLowEndGraph setPlotMode:CURVE_ONLY];
    [motorLowEndGraph setCurveFromArray:lowEndCoefficients count:6];
    [motorLowEndGraph rescaleForCurveWithRange:0 :max checkInterval:max/100];

    [inspectorPanel display];
    return self;
}

- setBatteryBox:anObject;
{
    batteryBox = anObject;
    boxList[7] = anObject;
    return self;
}

- OKBatteryBox:sender
{
float ampCoefficients[6];
float voltCoefficients[6];
int i;

    for ( i = 0 ; i < 6 ; i++ )
        ampCoefficients[i] = [batteryAmpCoefficients floatValueAt:i];
    [battery setAmpCoefficients:ampCoefficients];
    [battery setEfficiency:[batteryEfficiency floatValue]];
    [battery setMass:[batteryMass floatValue]];
    [battery setMax:[batteryMax floatValue]];
    [battery setPeakDraw:[batteryPeakDraw floatValue]];
    [battery setPlotAmps:[batteryPlotAmps state]];
    [battery setPlotCharge:[batteryPlotCharge state]];
    [battery setPlotVolts:[batteryPlotVolts state]];
    [battery setPresent:[batteryPresent doubleValue]];
    for ( i = 0 ; i < 6 ; i++ )
        voltCoefficients[i] = [batteryVoltCoefficients floatValueAt:i];
    [battery setVoltCoefficients:voltCoefficients];

    [batteryVoltGraph setPlotMode:CURVE_ONLY];
    [batteryVoltGraph setCurveFromArray:voltCoefficients count:6];
    [batteryVoltGraph rescaleForCurveWithRange:0 :[batteryMax floatValue] checkInterval:[batteryMax floatValue]/100];

    [batteryAmpGraph setPlotMode:CURVE_ONLY];
    [batteryAmpGraph setCurveFromArray:ampCoefficients count:6];
    [batteryAmpGraph rescaleForCurveWithRange:0 :[batteryMax floatValue] checkInterval:[batteryMax floatValue]/100];

    [inspectorPanel display];
  
    return self;
}

- revertBatteryBox:sender
{
float *ampCoefficients;
float *voltCoefficients;
int i;

    ampCoefficients = [battery ampCoefficients];
    for ( i = 0 ; i < 6 ; i++ )
        [batteryAmpCoefficients setFloatValue:ampCoefficients[i] at:i];
    [batteryEfficiency setFloatValue:[battery efficiency]];
    [batteryMass setFloatValue:[battery mass]];
    [batteryMax setFloatValue:[battery max]];
    [batteryPeakDraw setFloatValue:[battery peakDraw]];
    [batteryPlotAmps setState:[battery plotAmps]];
    [batteryPlotCharge setState:[battery plotCharge]];
    [batteryPlotVolts setState:[battery plotVolts]];
    [batteryPresent setDoubleValue:[battery present]];
    voltCoefficients = [battery voltCoefficients];
    for ( i = 0 ; i < 6 ; i++ )
        [batteryVoltCoefficients setFloatValue:voltCoefficients[i] at:i];

    [batteryVoltGraph setPlotMode:CURVE_ONLY];
    [batteryVoltGraph setCurveFromArray:voltCoefficients count:6];
    [batteryVoltGraph rescaleForCurveWithRange:0 :[batteryMax floatValue] checkInterval:[batteryMax floatValue]/100];

    [batteryAmpGraph setPlotMode:CURVE_ONLY];
    [batteryAmpGraph setCurveFromArray:ampCoefficients count:6];
    [batteryAmpGraph rescaleForCurveWithRange:0 :[batteryMax floatValue] checkInterval:[batteryMax floatValue]/100];

    [inspectorPanel display];

    return self;
}

- setWheelBox:anObject;
{
    wheelBox = anObject;
    boxList[8] = anObject;
    return self;
}

- OKWheelBox:sender
{
    [wheel setDiameter:[wheelDiameter floatValue]];
    [wheel setMass:[wheelMass floatValue]];
    [wheel setRollingResistance:[wheelRollingResistance floatValue]];
    return self;
}

- revertWheelBox:sender
{
    [wheelDiameter setFloatValue:[wheel diameter]];
    [wheelMass setFloatValue:[wheel mass]];
    [wheelRollingResistance setFloatValue:[wheel rollingResistance]];
    return self;
}

- setCycleBox:anObject;
{
    cycleBox = anObject;
    boxList[9] = cycleBox;
    return self;
}

- OKCycleBox:sender
{
    [cycle setEnd:[cycleEnd floatValue]];
    [cycle setStart:[cycleStart floatValue]];
    return self;
}


- revertCycleBox:sender
{
    [cycleEnd setFloatValue:[cycle end]];
    [cycleStart setFloatValue:[cycle start]];
    return self;
}

- loadCycle:sender;
{
char *filename;

    filename = [appDelegate openFileType:"cycle"];
    [self updateCycleGraph:filename];
    return self;
}

- updateCycleGraph:(const char *)filename
{
    strcpy(windowTitles[9],filename);
    [cycleGraph setData:[cycle data]];
    [cycleGraph setZeroLines:NO];
    [inspectorPanel setTitleAsFilename:windowTitles[9]];
    [cycleStart setFloatValue:[cycleGraph xmin]];
    [cycleEnd setFloatValue:[cycleGraph xmax]];
    [cycle setLength:[cycleGraph xmax]];
    [cycleLength setFloatValue:[cycle length]];
    [self OKCycleBox:self];
    [inspectorPanel display];
    return self;    
}

- flipInspector:sender
{
int i;
id view;

    [self updateBoxes];
    i = [sender tag];
    view = [boxList[i] contentView];
    [inspectorPanel setTitleAsFilename:windowTitles[i]];
    [inspectorBox setContentView:view];
    [inspectorBox display];
    return self;
}

- updateBoxes
{
    [self revertRoadBox:self];
    [self revertCarBox:self];
    [self revertControllerBox:self];
    [self revertTransmissionBox:self];
    [self revertEngineBox:self];
    [self revertGasTankBox:self];
    [self revertMotorBox:self];
    [self revertBatteryBox:self];
    [self revertWheelBox:self];
    [self revertCycleBox:self];
    return self;
}

@end
