//  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)gt{ return gt;}
- (double)gs{ return gs;}
- (double)pt{ return pt;}
- (double)gf{ return gf;}
- (double)tt{ return tt;}
- (double)tc{ return tc;}
- (double)mt{ return mt;}
- (double)ma{ return ma;}
- (double)pm{ return pm;}
- (double)cc{ return cc;}
- (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)setGt:(double)aVal {gt = aVal; return self;}
- (id)setGs:(double)aVal {gs = aVal; return self;}
- (id)setPt:(double)aVal {pt = aVal; return self;}
- (id)setGf:(double)aVal {gf = aVal; return self;}
- (id)setTt:(double)aVal {tt = aVal; return self;}
- (id)setTc:(double)aVal {tc = aVal; return self;}
- (id)setMt:(double)aVal {mt = aVal; return self;}
- (id)setMa:(double)aVal {ma = aVal; return self;}
- (id)setPm:(double)aVal {pm = aVal; return self;}
- (id)setCc:(double)aVal {cc = aVal; return self;}
- (id)setFlag:(int)aVal {flag = 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];
	time = ((double)tmp)/60./60.;
		
	[self double:scanner item:&lat];
	[self double:scanner item:&lon];
	[self double:scanner item:&gt];
	[self double:scanner item:&gs];
	[self double:scanner item:&pt];
	[self double:scanner item:&gf];
	[self double:scanner item:&tt];
	[self double:scanner item:&tc];
	[self double:scanner item:&mt];
	[self double:scanner item:&ma];
	[self double:scanner item:&pm];
	[self double:scanner item:&cc];
	[self int:scanner item:&flag];
	return self;
}

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

- (id)init
{	
	if (self = [super init]) {
		time = lat = lon = gt = gf = tt = tc = mt = ma = gs = pt = pm = cc = NAN;
		flag = tag = -1;
	}
	return self;
}

- (id)initTo:(double)aVal
{
	[self init];
	time = lat = lon = gt = gf = tt = tc = mt = ma = gs = pt = pm = cc = aVal;
	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 GT_FIELD: return [self gt];
		case GS_FIELD: return [self gs];
		case PT_FIELD: return [self pt];
		case GF_FIELD: return [self gf];
		case TT_FIELD: return [self tt];
		case TC_FIELD: return [self tc];
		case MT_FIELD: return [self mt];
		case MA_FIELD: return [self ma];
		case PM_FIELD: return [self pm];
		case CC_FIELD: return [self cc];
	}
	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 GT_FIELD: return [self setGt:aVal];
		case GS_FIELD: return [self setGs:aVal];
		case PT_FIELD: return [self setPt:aVal];
		case GF_FIELD: return [self setGf:aVal];
		case TT_FIELD: return [self setTt:aVal];
		case TC_FIELD: return [self setTc:aVal];
		case MT_FIELD: return [self setMt:aVal];
		case MA_FIELD: return [self setMa:aVal];
		case PM_FIELD: return [self setPm:aVal];
		case CC_FIELD: return [self setCc:aVal];
	}
	NSRunAlertPanel(@"GmtShipTrackRecord.m", @"Field is not known",nil,nil,nil);
	return nil;
}

- (NSMutableString *)stringRep
{
	NSMutableString *tmp = [[NSMutableString stringWithCapacity:1000] retain];
	
	[tmp appendFormat:@"%ld",(long)([self time]*60*60)];
	[tmp appendFormat:@"%10.5f",[self lat]];
	[tmp appendFormat:@"%10.5f",[self lon]];
	
	int i;
	for (i=GT_FIELD; i<=CC_FIELD; i++) {
				
		// FIXME: need some !@#$%^&* way to encode NaN cleanly...		
		double x = [self data:i];
		int poo = round(x);
		if (poo==-2147483648)
		{
			[tmp appendFormat:@"       NaN"];	// match the spacing in the .dat file we are using...

		} 
		else
		{
			[tmp appendFormat:@"%10d", poo];
		}
	}
	[tmp appendFormat:@"%10d\n", [self flag]];
	return tmp;
}

- (int)predictedFieldForActualField:(int)actualField {
	
	switch (actualField) {
		case MA_FIELD : return PM_FIELD; 
		case GF_FIELD : return GS_FIELD; 
		case GT_FIELD : return GS_FIELD; 
		case TC_FIELD : return PT_FIELD; 
		case TT_FIELD : return PT_FIELD; 
		default:
			return actualField; 
	}
}

- (double)predictedData:(int)fieldNum {
	switch (fieldNum) {
		case MA_FIELD : 
		case GF_FIELD : 
		case GT_FIELD : 
		case TC_FIELD : 
		case TT_FIELD : 
			return [self data:[self predictedFieldForActualField:fieldNum]];
		default:
			return 0.0;
	}
}

@end
