//=============================================================================
//
//		Copyright (C) 1996 by Paul S. McCarthy and Eric Sunshine.
//				Written by Paul S. McCarthy and Eric Sunshine.
//							All Rights Reserved.
//
//		This notice may not be removed from this source code.
//
//		This object is included in the MiscKit by permission from the authors
//		and its use is governed by the MiscKit license, found in the file
//		"License.rtf" in the MiscKit distribution.	Please refer to that file
//		for a list of all applicable permissions and restrictions.
//
//=============================================================================
//-----------------------------------------------------------------------------
// MiscExporter.M
//
//		Object that exports the contents of an MiscTableScroll in
//		various useful formats.
//
// TODO:
//		* Genericize for use with Matrix, DBTableView.
//		* Add more export formats: rtf0, Lotus 1-2-3, Quattro, Excel, etc.
//		* Maybe provide option for <CR><LF> line terminators.
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// $Id: MiscExporter.M,v 1.3 96/09/25 17:34:12 zarnuk Exp $
// $Log:		MiscExporter.M,v $
// Revision 1.3	 96/09/25  17:34:12	 zarnuk
// syntax errors.
// 
// Revision 1.2	 96/09/25  17:09:16	 zarnuk
// Added commonInstance.  exportTableScroll:(toFilename:) methods now return
// an integer success/fail code.
// 
// Revision 1.1	 96/09/25  11:54:21	 zarnuk
// Exports the contents of table scroll in various formats.
// 
//-----------------------------------------------------------------------------
#import "MiscExporterPrivate.h"
#import "MiscExporterAccessoryView.h"
#import <misckit/MiscTableScroll.h>

extern "Objective-C" {
#import <appkit/SavePanel.h>
}

extern "C" {
#import <errno.h>
#import <stdio.h>
#import <stdlib.h>				// malloc(), free()
#import <string.h>				// memcpy(), strlen()
}


//=============================================================================
// MiscExporter
//=============================================================================
@implementation MiscExporter

- (MiscExportFormat) getExportFormat			{ return exportFormat; }
- (MiscExportTitleMode) getRowExportTitleMode	{ return rowTitleMode; }
- (MiscExportTitleMode) getColExportTitleMode	{ return colTitleMode; }
- (MiscExportGridMode) getRowExportGridMode		{ return rowGrid; }
- (MiscExportGridMode) getColExportGridMode		{ return colGrid; }

- (void) setExportFormat:(MiscExportFormat)x			{ exportFormat = x; }
- (void) setRowExportTitleMode:(MiscExportTitleMode)x	{ rowTitleMode = x; }
- (void) setColExportTitleMode:(MiscExportTitleMode)x	{ colTitleMode = x; }
- (void) setRowExportGridMode:(MiscExportGridMode)x		{ rowGrid = x; }
- (void) setColExportGridMode:(MiscExportGridMode)x		{ colGrid = x; }


//-----------------------------------------------------------------------------
// rowTitleCharWidth:
//-----------------------------------------------------------------------------
- (int) rowTitleCharWidth:(int) nrows
	{
	int max_width = 0;
	if (rowTitleMode != MISC_EXPORT_TITLES_OFF)
		for (int r = 0; r < nrows; r++)
			{
			int const len = safe_strlen( row_title( r, tableScroll ) );
			if (max_width < len)
				max_width = len;
			}
	return max_width;
	}


//-----------------------------------------------------------------------------
// makeColMap:
//-----------------------------------------------------------------------------
- (int*) makeColMap:(int)ncols
	{
	int* col_map = (int*) malloc( ncols * sizeof(*col_map) );
	for (int c = 0; c < ncols; c++)
		col_map[c] = col_at( c, tableScroll );
	return col_map;
	}


//-----------------------------------------------------------------------------
// exportToFile:
//-----------------------------------------------------------------------------
- (void) exportToFile:(FILE*)fp
	{
	switch (exportFormat)
		{
		default:
		case MISC_EXPORT_ASCII_FIXED:	[self exportFixed:fp];	break;
		case MISC_EXPORT_ASCII_TAB:		[self exportTab:fp];	break;
		case MISC_EXPORT_ASCII_DELIMITED:[self exportDelimited:fp];break;
		case MISC_EXPORT_DBF:			[self exportDBF:fp];	break;
		}
	}


//-----------------------------------------------------------------------------
// exportToFilename:
//-----------------------------------------------------------------------------
- (int) exportToFilename:(char const*)nm
	{
	int rc = 0;
	FILE* fp = fopen( nm, "wb" );
	if (fp == 0)
		rc = errno;
	else
		{
		[self exportToFile:fp];
		rc = fclose( fp );
		}
	return rc;
	}


//-----------------------------------------------------------------------------
// createAccessorView
//-----------------------------------------------------------------------------
- (MiscExporterAccessoryView*) createAccessoryView
	{
	return (MiscExporterAccessoryView*)
		[[MiscExporterAccessoryView alloc]
				initFrame:0
				format:exportFormat
				rowTitle:rowTitleMode
				colTitle:colTitleMode
				rowGrid:rowGrid
				colGrid:colGrid];
	}


//-----------------------------------------------------------------------------
// getValuesFromAccessoryView:
//-----------------------------------------------------------------------------
- (void) getValuesFromAccessoryView:(MiscExporterAccessoryView*)view
	{
	[self setExportFormat:[view format]];
	[self setRowExportTitleMode:[view rowTitleMode]];
	[self setColExportTitleMode:[view colTitleMode]];
	[self setRowExportGridMode:[view rowGrid]];
	[self setColExportGridMode:[view colGrid]];
	}


//-----------------------------------------------------------------------------
// exportTableScroll:
//-----------------------------------------------------------------------------
- (int) exportTableScroll:(MiscTableScroll*)ts
	{
	int rc = -1;
	if (ts != 0 && [ts numCols] > 0)
		{
		tableScroll = ts;
		SavePanel* panel = [SavePanel new];
		id old_delg = [panel delegate];
		View* old_view = [panel accessoryView];
		MiscExporterAccessoryView* view = [self createAccessoryView];

		[panel setDelegate:self];
		[panel setAccessoryView:view];
		[panel makeKeyAndOrderFront:0];
		if ([panel runModal] == NX_OKTAG)
			{
			[self getValuesFromAccessoryView:view];
			if ((rc = [self exportToFilename:[panel filename]]) != 0)
				NXRunAlertPanel( "Error", "Cannot open %s.\n%s",
					"OK",0,0, [panel filename], strerror(rc) );
			}
		[panel close];
		[panel setAccessoryView:old_view];
		[panel setDelegate:old_delg];

		[view free];
		}

	return rc;
	}


//-----------------------------------------------------------------------------
// exportTableScroll:toFilename:
//-----------------------------------------------------------------------------
- (int) exportTableScroll:(MiscTableScroll*)ts toFilename:(char const*) nm
	{
	int rc = -1;
	if (nm != 0 && ts != 0 && [ts numCols] > 0)
		{
		tableScroll = ts;
		rc = [self exportToFilename:nm];
		}
	return rc;
	}


//-----------------------------------------------------------------------------
// init
//-----------------------------------------------------------------------------
- init
	{
	[super init];
	rowTitleMode = MISC_EXPORT_TITLES_ROW_DEFAULT;
	colTitleMode = MISC_EXPORT_TITLES_COL_DEFAULT;
	rowGrid = MISC_EXPORT_GRID_ROW_DEFAULT;
	colGrid = MISC_EXPORT_GRID_COL_DEFAULT;
	return self;
	}


//-----------------------------------------------------------------------------
// + commonInstance
//-----------------------------------------------------------------------------
+ (MiscExporter*) commonInstance
	{
	static MiscExporter* obj = 0;
	if (obj == 0)
		obj = [[self alloc] init];
	return obj;
	}

@end
