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

#import "StatView.h"
#import "DataView.h"
#import "NavigationView.h"
#import "GMTShipTrack.h"

@implementation StatView

- (void)awakeFromNib
{
	[super awakeFromNib];
	
	[meanCell   setDoubleValue:-1];
	[stdDevCell setDoubleValue:-2];
	[slopeCell  setDoubleValue:-3];
	[offsetCell setDoubleValue:-4];
	[countCell  setDoubleValue:-5];
	
	dataTypeBeingPlotted = [[dataTypeField selectedItem] tag];
}

- (NSPoint)dataPtAtRecord:(GmtShipTrackRecord *)obj
{
	return NSMakePoint([obj predictedData:[self dataTypeBeingPlotted]], 
					   [obj data:[self dataTypeBeingPlotted]]);
}

- (void)mouseMoved:(NSEvent *)theEvent
{
	distanceToLine = 3.;
	hotSpotIsCenterOfSegment = NO;
	[super mouseMoved:theEvent];
	
	float timeAtCursor = [objAtCursor time] - [[[[controller gmtShipTrack] gmtShipTrackRecordList] objectAtIndex:0] time];
	
	if (hotSpotFound)
	{
		[(NavigationView *)	[[controller navController]  graphView] moveCursorToRecord:objAtCursor];
		[(DataView *)		[[controller dataController] graphView] moveCursorToRecord:objAtCursor];
		[tCell setStringValue:[NSString stringWithFormat:@"t: %12.5f", timeAtCursor] ];
	}
	else
	{
		[(NavigationView *)	[[controller navController]	 graphView] dataMissing];		
		[(DataView *)		[[controller dataController] graphView] dataMissing];
		[tCell setStringValue:@"t: no t seg"];
	}
}	

- (void)addDataToDisplayList:(int)dataField
{
	GmtShipTrackRecord	*obj= [[[controller gmtShipTrack] gmtShipTrackRecordList] objectAtIndex:0];
	NSEnumerator		*en = [[[controller gmtShipTrack] gmtShipTrackRecordList] objectEnumerator];
	NSPoint dataPt;
	
	first = YES;
	
	while (obj = [en nextObject]) {
		
		switch (dataField) {
			case DEPTH_FIELD : dataPt = NSMakePoint([obj predictedDepth], [obj depth]); break;
			default:
				NSRunAlertPanel(nil,@"StatController.m changedDataPlotted: User selected a unexpected data tag.",nil,nil,nil);
		}
		
		if (!isnan(dataPt.y) && !isnan(dataPt.x))
		{
			if (!first) 
			{
				Tick *tick = [[[Tick alloc] initFrom:lastPt to:dataPt view:self record:obj] autorelease];
				//Segment *tick=[[[Segment alloc] initFrom:lastPt to:dataPt view:self record:obj] autorelease];
				if (([obj flag] & ~1) != 0) 
				{
					[tick  setLineType:SOLID_LINE]; 
					[tick  setTag:FLAG_TAG];
				}
				else
				{
					switch (dataField) {
						case DEPTH_FIELD : 
							[tick  setTag:MEASURED_TAG]; 
							[tick  setLineType:SOLID_LINE]; 
							break;
						default:
							[tick  setTag:PREDICTED_TAG];
							[tick  setLineType:SOLID_LINE]; 
					}
				}
				
				[self addGraphElement:tick];
			}
			
			first = NO;			// No longer first
			lastPt = dataPt;	// Remember this point
		}
	}
	
	// diagonal line with slope of 1, same color as axes
	Segment *seg = [[[Segment alloc] initFrom:NSMakePoint(-1000*1000, -1000*1000) to:NSMakePoint(+1000*1000, +1000*1000) view:self record:nil] autorelease];
	[seg setColor:[self colorForTag:AXES_TAG]];
	[self addGraphElement:seg];
}

- (IBAction)changeDataPlotted:(id)sender
{
	int i = [[dataTypeField selectedItem] tag];
	
	switch (i) {
		case DEPTH_FIELD : 
			dataTypeBeingPlotted = i;
			
			[self clear];
			
			float maxData = [[[controller gmtShipTrack] max] data:dataTypeBeingPlotted];
//			float minData = [[[controller gmtShipTrack] min] data:dataTypeBeingPlotted];
			
			if (isnan(maxData)) {
				[yminCell  setDoubleValue:0];
				[ymaxCell  setDoubleValue:0];
				return;
			}
				
			[self graph:sender];
			[self zoomToDataExtent:[controller gmtShipTrack]];
			
			break;
		default:
			NSRunAlertPanel(nil,@"StatController.m changedDataPlotted: User selected a unexpected data tag.",nil,nil,nil);
	}
	return;
}

- (void)gotData:(id)sender
{	
	[super gotData:sender];

	// Plot ship data vs predicted in the window
	
	[self addDataToDisplayList:[self dataTypeBeingPlotted]];
}

- (id)updateStatsFields
{
	[[controller gmtShipTrack] setDoubleWithNaN:countCell:	[[[controller gmtShipTrack] numGood]data:dataTypeBeingPlotted]];
	[[controller gmtShipTrack] setDoubleWithNaN:meanCell:	[[[controller gmtShipTrack] mean]	data:dataTypeBeingPlotted]];
	[[controller gmtShipTrack] setDoubleWithNaN:stdDevCell:	[[[controller gmtShipTrack] stdDev]	data:dataTypeBeingPlotted]];
	[[controller gmtShipTrack] setDoubleWithNaN:slopeCell:	[[[controller gmtShipTrack] slope]	data:dataTypeBeingPlotted]];
	[[controller gmtShipTrack] setDoubleWithNaN:offsetCell:	[[[controller gmtShipTrack] offset]	data:dataTypeBeingPlotted]];
	
	return self;
}

- (id)zoomToDataExtent:(GmtShipTrack *)gmtShipTrack
{
	
	// FIXME: this is a butt ugly and long winded way to find the min of min and max of max...
	double x0, x1, y0, y1;
	
	int i = [[dataTypeField selectedItem] tag];
	
	y0 = [[gmtShipTrack min] data:i];
	y1 = [[gmtShipTrack max] data:i];
		
	x0 = [[gmtShipTrack min] predictedData:i];
	x1 = [[gmtShipTrack max] predictedData:i];
	
	x0 = MIN(x0, y0);		// min of min
	x1 = MAX(x1, y1);		// max of max
	
	y0 = x0;
	y1 = x1;
	
	if (x1 > x0) {
		NSRect extent = NSMakeRect(x0, y0, x1-x0, y1-y0);	
		[self zoomToRect:extent];
	} else {
	}
	[self updateStatsFields];
	return self;
}

- (IBAction)zoomToFit:(id)sender {
	[self zoomToDataExtent:[controller gmtShipTrack]];
}

-(void)mouseDragged:(NSEvent *)theEvent
{
	[super mouseDragged:theEvent];
	weBeFlagging = NO;
	return;				
}

- (void)zoomToRect:(NSRect)rect 
{
	//	rect.origin.y = rect.origin.x;
	//	rect.size.width  = MAX(rect.size.height, rect.size.width);
	//	rect.size.height = rect.size.width;
	
	[super zoomToRect:rect];
}

@end
