//  Created by Joe Becker on 3/7/05.
//  Copyright 2005 __MyCompanyName__. All rights reserved.

#import "GmtShipTrackRecord.h"
#include <math.h>

@implementation GmtShipTrackRecord

- (double)time { return time;}
- (double)lat{ return lat;}
- (double)lon{ return lon;}
- (double)predictedDepth{ return predictedDepth;}
- (double)depth{ return depth;}
- (double)sigmaH{ return sigmaH;}
- (double)sigmaD{ return sigmaD;}
- (double)cc{ return cc;}
- (int)srcId{ return srcId;}	//FIXME: need to make flag some sort of bit fiddle
- (int)flag{ return flag;}		//FIXME: need to make flag some sort of bit fiddle

- (int)tag      { return tag; }

- (id)setTime:(double)aVal {time = aVal; return self;}
- (id)setLat:(double)aVal {lat = aVal; return self;}
- (id)setLon:(double)aVal {lon = aVal; return self;}
- (id)setPredicted_depth:(double)aVal {predictedDepth = aVal; return self;}
- (id)setDepth:(double)aVal {depth = aVal; return self;}
- (id)setSigmaH:(double)aVal {sigmaH = aVal; return self;}
- (id)setSigmaD:(double)aVal {sigmaD = aVal; return self;}
- (id)setCc:(double)aVal {cc = aVal; return self;}
- (id)setFlag:(int)aVal {flag = aVal; return self;}
- (id)setSrcId:(int)aVal {srcId = aVal; return self;}

// This is really not used; conceptually we would want a tag for the graphView objects to use...
- (id)setTag:(int)aTag {tag = aTag; return self;}

-(id)double: (NSScanner *)theScanner item: (double *)it 
{
	if(![theScanner scanDouble:it]) 
		[theScanner scanString:@"NaN" intoString:NULL];	
	return self;
}

-(id)int:(NSScanner *)theScanner item: (int *)it
{
	if(![theScanner scanInt:it]) 
		[theScanner scanString:@"NaN" intoString:NULL]; 
	return self;
}

- (id)setValuesFromScanner:(NSScanner *)scanner
{
	int tmp;
//	[self int:scanner item:&tmp];
//	[self double:scanner item:&lon];	
//	[self double:scanner item:&lat];
//	[self double:scanner item:&depth];
//	[self double:scanner item:&sigmaH];
//	[self double:scanner item:&sigmaD];	
//	[self int:scanner item:&srcId];
//	[self double:scanner item:&predictedDepth];

	[scanner scanInt:	&tmp];	// convert from int seconds to float hours below...
	[scanner scanDouble:&lon];
	[scanner scanDouble:&lat];
	[scanner scanDouble:&depth];
	[scanner scanDouble:&sigmaH];
	[scanner scanDouble:&sigmaD];
	[scanner scanInt:	&srcId];
	[scanner scanDouble:&predictedDepth];
	
	time = ((double)tmp)/60./60.;
	
	//FIXME: the flag be jacked; Jack.
	flag = (sigmaD == 9999) ? -1 : 0;
	if (predictedDepth == 9999)
		predictedDepth = NAN;
	return self;
}

- (id)setValuesFromString:(NSString *)str
{
	return [self setValuesFromScanner:[NSScanner scannerWithString:str]];
}

- (id)init
{	
	if (self = [super init]) {
		time = lat = lon = depth = sigmaH = sigmaD = predictedDepth = cc = NAN;
		srcId = flag = tag = -1;
	}
	return self;
}

- (id)initTo:(double)aVal
{
	[self init];
	time = lat = lon = depth = sigmaH = sigmaD = predictedDepth = cc = aVal;
	srcId = flag = tag = -1;
	return self;
}

- (id)initFromScanner:(NSScanner *)scanner
{
	return [[self init] setValuesFromScanner:scanner];
}

- (id)initFromString:(NSString *)str
{
	return [[self init] setValuesFromString:str];
}

- (double)data:(int)fieldNum
{
	switch (fieldNum) {
		case TIME_FIELD: return [self time];
		case LAT_FIELD: return [self lat];
		case LON_FIELD: return [self lon];
		case PREDICTED_DEPTH_FIELD: return [self predictedDepth];
		case DEPTH_FIELD: return [self depth];
		case SIGMA_H_FIELD: return [self sigmaH];
		case SIGMA_D_FIELD: return [self sigmaD];
		case SOURCE_ID_FIELD: return [self srcId];
	}
	NSRunAlertPanel(@"GmtShipTrackRecord.m", @"Field is not known",nil,nil,nil);
	return NAN;
}

- (id)setData:(int)fieldNum :(double)aVal
{
	switch (fieldNum) {
		case TIME_FIELD: return [self setTime:aVal];
		case LAT_FIELD: return [self setLat:aVal];
		case LON_FIELD: return [self setLon:aVal];
		case PREDICTED_DEPTH_FIELD: return [self setPredicted_depth:aVal];
		case DEPTH_FIELD: return [self setDepth:aVal];
		case SIGMA_H_FIELD: return [self setSigmaH:aVal];
		case SIGMA_D_FIELD: return [self setSigmaD:aVal];
		case SOURCE_ID_FIELD: return [self setSrcId:aVal];
	}
	NSRunAlertPanel(@"GmtShipTrackRecord.m", @"Field is not known",nil,nil,nil);
	return nil;
}

- (NSMutableString *)stringRep
{
	NSMutableString *tmp = [[NSMutableString stringWithCapacity:1234] retain];
	
	[tmp appendFormat:@"%ld",(long)([self time]*60*60)];
	[tmp appendFormat:@" %.5f",[self lon]];
	[tmp appendFormat:@" %.5f",[self lat]];
	
	int i;
	for (i=DEPTH_FIELD; i<=PREDICTED_DEPTH_FIELD; i++) {
				
		double x = [self data:i];

		//FIXME: more Sandwell hackery....
		if (i == SIGMA_D_FIELD && flag != 0)
			x = 9999;
		
		//FIXME: hack in NaN as 9999....
		if (isnan(x))
		{
			[tmp appendFormat:@" 9999"];	// match the spacing in the .cm file we are using...

		} 
		else
		{
			[tmp appendFormat:@" %d", (int)x];
		}
	}
	[tmp appendFormat:@"\n"];
	return tmp;
}

- (int)predictedFieldForActualField:(int)actualField {
	
	switch (actualField) {
		case DEPTH_FIELD : return PREDICTED_DEPTH_FIELD; 
		default:
			return actualField; 
	}
}

- (double)predictedData:(int)fieldNum {
	switch (fieldNum) {
		case DEPTH_FIELD : 
			return [self data:[self predictedFieldForActualField:fieldNum]];
		default:
			return 0.0;
	}
}

@synthesize fieldList;
@synthesize predictedDepth;
@end
