#include "ULAnalyserDataSetView.h"

@implementation ULAnalyserDataSetView

- (id) init
{	
	if(self = [super init])
	{
		//Controls the width of the cells in the table view
		//so we can always see a four decimal floating point number.
		//We should be able to remove this if NSNumberFormatter is implemented.

		defaultWidth = [[NSFont userFontOfSize: 12] widthOfString:
				[NSString stringWithFormat: @"%.4e", 0.0]];
		defaultWidth +=10;
		dataSet = nil;
		currentTable = nil;
		terms = nil;
	}	

	return self;
}

- (void) dealloc
{
	[terms release];
	[dataSet release];
	[super dealloc];
}

- (void)awakeFromNib
{
	[resultsTable setAllowsColumnReordering: YES];
	[resultsTable setAllowsColumnResizing: YES];
	[resultsTable setDataSource: self];
	[resultsTable setDelegate: self];
	[resultsTable sizeToFit];
	[displayList removeAllItems];
}


- (void) setDataSet: (AdDataSet*) aDataSet
{
	if(aDataSet != dataSet)
		[dataSet release];
	dataSet = [aDataSet retain];	
}

- (id) dataSet
{
	return dataSet;	
}

- (NSArray*) _genericHeadersForColumns: (int) number
{
	int i;
	NSMutableArray* array = [NSMutableArray array];

	for(i=0; i<number; i++)
		[array addObject: [NSString stringWithFormat: @"Column %d", i]];
	
	return array;
}

- (void) _displayCurrentDataSetTable
{
	int i;
	int currentNumberOfColumns, requiredNumberOfColumns, diff;
	id subsystem, newColumn, columns;
	NSRange range;

	NS_DURING
	{
		requiredNumberOfColumns = [currentTable numberOfColumns];
		currentNumberOfColumns = [resultsTable numberOfColumns];
		columns = [resultsTable tableColumns];
	
		[terms release];
		terms = [currentTable columnHeaders];
		if(terms == nil)
		{
			terms = [self _genericHeadersForColumns: requiredNumberOfColumns];
			[currentTable setColumnHeaders: terms];
		}	
		[terms retain];

		if(currentNumberOfColumns < requiredNumberOfColumns)
		{
			for(i=0; i<currentNumberOfColumns; i++)
			{
				[[[columns objectAtIndex: i] headerCell]
					 setObjectValue: [terms objectAtIndex: i]];

				[[columns objectAtIndex: i] sizeToFit];
				if([[columns objectAtIndex: i] width] < defaultWidth)
					[[columns objectAtIndex: i] setWidth: defaultWidth];

				[[columns objectAtIndex: i] setIdentifier:[terms objectAtIndex: i]];
				[[[columns objectAtIndex: i] dataCell]
					setAlignment: NSCenterTextAlignment];
			}

			for(i=currentNumberOfColumns; i<requiredNumberOfColumns; i++)
			{
				newColumn = [[NSTableColumn alloc] 
						initWithIdentifier: [terms objectAtIndex: i]];
				[[newColumn headerCell] setObjectValue: [terms objectAtIndex: i]];
				[newColumn sizeToFit];
				
				if([newColumn width] < defaultWidth)
					[newColumn setWidth: defaultWidth];

				[[newColumn dataCell] setAlignment: NSCenterTextAlignment];
				[resultsTable addTableColumn: newColumn];
				[newColumn autorelease];
			}
		}
		else
		{
			for(i=0; i<requiredNumberOfColumns; i++)
			{
				[[[columns objectAtIndex: i] headerCell]
				 	setObjectValue: [terms objectAtIndex: i]];
				[[columns objectAtIndex: i] setIdentifier:[terms objectAtIndex: i]];
				[[columns objectAtIndex: i] sizeToFit];

				if([[columns objectAtIndex: i] width] < defaultWidth)
					[[columns objectAtIndex: i] setWidth: defaultWidth];

				[[[columns objectAtIndex: i] dataCell] 
					setAlignment: NSCenterTextAlignment];
			}

			for(i=requiredNumberOfColumns; i<currentNumberOfColumns; i++)
				[resultsTable removeTableColumn: [columns objectAtIndex: i]];
		}

		[resultsTable setNeedsDisplay: YES];
		[resultsTable reloadData];
		[self outputDataTableForGnuplot];
	}
	NS_HANDLER
	{
		NSRunAlertPanel(@"Alert", [localException reason], @"Dismiss", nil, nil);
	}
	NS_ENDHANDLER
}

- (void) displayData
{
	NSEnumerator* dataSetTablesEnum;
	NSMutableArray* tableNames = [NSMutableArray array];
	NSString* name;
	AdDataMatrix* table;
	
	dataSetTablesEnum = [[dataSet dataMatrices] objectEnumerator];
	while(table = [dataSetTablesEnum nextObject])
	{
		name = [table name];
		if(name != nil)
			[tableNames addObject: name];
		else
			[tableNames addObject: @"Table One"];
	}

	[displayList removeAllItems];
	[displayList addItemsWithTitles: tableNames];
	[displayList selectItemAtIndex: 0];
	currentTable = [[dataSet dataMatrices] objectAtIndex: 0];

	if(currentTable != nil)
		[self _displayCurrentDataSetTable];
}

- (void) outputDataTableForGnuplot
{
	int i, j, noColumns, index;
	id currentOrder, column;
	NSEnumerator* columnEnum;
	FILE* energyFile;

	energyFile =  fopen([[[[ULIOManager appIOManager] 
					applicationDir] 
					stringByAppendingPathComponent: @"Results"] cString] , "w");

	currentOrder = [NSMutableArray arrayWithCapacity: 1];
	columnEnum = [[resultsTable tableColumns] objectEnumerator];
	while(column = [columnEnum nextObject])
		[currentOrder addObject: [[column headerCell] stringValue]];

	noColumns = [currentOrder count];
	for(i=0; i<[currentTable numberOfRows]; i++)
	{
		for(j=0; j<noColumns;j++)
		{
			index = [terms indexOfObject: [currentOrder objectAtIndex: j]];
			fprintf(energyFile, "%-12.4lf", 
				[[currentTable elementAtRow: i column:index] doubleValue]);
		}
		fprintf(energyFile, "\n");
	}
	fclose(energyFile);
}

- (void) selectedNewTableItem: (id) sender
{
	int index;

	index = [displayList indexOfSelectedItem];
	currentTable = [[dataSet dataMatrices] objectAtIndex: index];
	
	if(currentTable != nil)
		[self _displayCurrentDataSetTable];
}

- (void) clearDataSet
{
	int i, currentNumberOfColumns;
	id columns;

	[displayList removeAllItems];
	[dataSet release];
	dataSet = nil;
	currentTable = nil;

	currentNumberOfColumns = [resultsTable numberOfColumns];
	columns = [resultsTable tableColumns];

	for(i=0; i<currentNumberOfColumns; i++)
	{
		[[[columns objectAtIndex: i] headerCell]
			 	setObjectValue: @""];
		[[columns objectAtIndex: i] setIdentifier:@""];
		[[columns objectAtIndex: i] sizeToFit];
	}

	[resultsTable sizeToFit];
	[resultsTable setNeedsDisplay: YES];
	[resultsTable reloadData];
}


/*******************

Table Delegate Methods

*******************/

- (void) tableViewColumnDidMove: (NSNotification*) aNotification
{
	[self outputDataTableForGnuplot];
}

/******************

TableData Source methods

********************/

- (int)numberOfRowsInTableView:(NSTableView *)aTableView
{
	return [currentTable numberOfRows];
}

- (id)tableView:(NSTableView *)aTableView 
	objectValueForTableColumn:(NSTableColumn *)aTableColumn 
	row:(int)rowIndex
{
	int index;
	id value;

	index = [terms indexOfObject: [aTableColumn identifier]];
	value = [currentTable elementAtRow: rowIndex column: index];

	//FIXME: temporary hack until I think of something better
	//or NSNumberFomatter is implemented.

	if([value isKindOfClass: [NSNumber class]])
		value = [NSString stringWithFormat: @"%.4e", [value doubleValue]];

	return value;
}

@end

