#import <stdio.h>
#import <string.h>
#import "TeXfigApplication.h"
#import "TeXfigImageView.h"




@interface TeXitem: Object
{
	char *text;
	id image;
	BOOL printer;	
}
- text:(char*)newText;
- (char*)text;
- image:newImage;
- image;
- init;
- free;
- (BOOL)usePrinter;
- usePrinter:(BOOL)flag;
- write:(NXTypedStream*)typedStream;
- read:(NXTypedStream*)typedStream;
@end

@implementation TeXitem


- write:(NXTypedStream*)typedStream
{
	int printerVar,length;
	char buf[1];
	[super write:typedStream];
	printerVar = (printer)?1:0;
	if(text==NULL) length=0;
	else length = strlen(text);
	NXWriteTypes(typedStream,"ii", &printerVar,&length);
	if(text==NULL) {
		buf[0]='\0';
		NXWriteType(typedStream,"*",&buf);
	} else NXWriteType(typedStream,"*",&text);
	
	NXWriteRootObject(typedStream,image);
	return self;
}

- read:(NXTypedStream*)typedStream
{
	int printerVar, length;
	[super read:typedStream];
	NXReadTypes(typedStream,"ii",&printerVar,&length);
	if(printerVar) printer=YES;
	else printer=NO;
	text = (char*)calloc(length+1,sizeof(char));
	NXReadType(typedStream,"*",&text);
	text[length]='\0';
	image = NXReadObject(typedStream);
	return self;
}


- (BOOL)usePrinter
{
	return printer;
}

- usePrinter:(BOOL)flag
{
	printer = flag;
	return self;
}

- init
{
	text=NULL;
	image=nil;
	printer=NO;
	return self;
}

- free
{
	if(text==NULL) free(text);
	[image free];
	[super free];
	return self;
}


- text:(char*)newText
{
	if(text!=NULL) {
		free(text);
	}
	if(newText==NULL) {
		text=NULL;
		return self;
	}
	text = (char*)calloc(strlen(newText)+1,sizeof(char));
	strcpy(text,newText);

	return self;
}
- (char*)text
{
	return text;
}
- image: newImage
{
	if(image!=nil) [image free];
	image = newImage;
	return self;
}
- image
{
	return image;
}

@end




@implementation TeXfigApplication


- appDidInit:sender
{
	if(!strlen(filename)){
		imageList = [[List new] init];
		currentTeX=nil;
		[self insert: self];
		printer=NO;
		[[imageView window] setTitleAsFilename:"Untitled"];
		strcpy(filename,"");
	}
	return self;
}

- printer:sender
{
	printer=YES;
	[screenButton setState: NO];
	if(![printerButton state]) [printerButton setState:YES];
	if(currentTeX!=nil) [currentTeX usePrinter:YES];
	return self;
}
- screen:sender
{
	printer=NO;
	[printerButton setState: NO];
	if(![screenButton state]) [screenButton setState:YES];
	if(currentTeX!=nil) [currentTeX usePrinter:NO];
	return self;
}



- newTeXitem: newItem
{
	if(newItem==nil) return self;

	currentTeX=newItem;
	[inputText selectAll: self]; 
	[inputText setText:[newItem text]];
	[imageView newImage:[newItem image]];

	// set the buttons to reflect the printer status
	if([newItem usePrinter]) [self printer:self];
	else [self screen:self];

	return self;
}




- doit:sender
{
	char buffer[1024], tmpfilename[512];
	char TeXfilename[1024];
	char epsfilename[1024];
	char TeXbuffer[10000];
	char scratch[1000];
	id newimage;
	FILE *fpout;

	chdir("/tmp");
	// retreive the text from the text object
	[inputText 	getSubstring:(char *)buffer
			start:(int)0 
			length:(int)[inputText textLength]];
	buffer[[inputText textLength]]='\0';

	if(currentTeX!=nil) [currentTeX text:buffer];



	// run it through TeX
	sprintf(TeXbuffer,"\\documentstyle[times,fleqn,12pt]{article}\n\
\\nonstopmode\n\
\\parindent=0in\n\
\\mathindent=0in\n\
\\pagestyle{empty}\n\
\\begin{document}\n\
%s\n\
\\end{document}\n",buffer);

	tmpnam(tmpfilename);
	strcpy(TeXfilename,tmpfilename);
	strcat(TeXfilename,".tex");
	fpout = fopen(TeXfilename,"w");
	fprintf(fpout,"%s",TeXbuffer);
	fclose(fpout);
	sprintf(scratch,"latex %s",TeXfilename);
	system(scratch); 

	// run it through dvips
	strcpy(epsfilename,tmpfilename);
	strcat(epsfilename,".eps");
	sprintf(scratch,"dvips -x 2000 -E -f -D %d %s.dvi > %s",
		(printer)?400:72,tmpfilename,epsfilename); 
	system(scratch);

	// retreive the image and get it displayed
	newimage = [[NXImage alloc] init];
	[newimage loadFromFile: epsfilename];
	//[newimage setEPSUsedOnResolutionMismatch: YES];
    	[newimage setDataRetained:YES];
        [newimage setScalable:YES];

	[imageView newImage: newimage];

	if(currentTeX!=nil) [currentTeX image: newimage];

    return self;
}

- cut: sender
{
	return self;
	[self copy: sender];
	return self;
}
- copy: sender
{
	[imageView copy: self];
	return self;
}

- delete: sender
{
	int i;

	return self;
}

- newText:(char*)newText
{
	[inputText selectAll: self]; 
	[inputText setText:newText];
	//printf("new text is %s\n",newText);
	//[inputText update];
	return self;
}

- up: sender
{
	unsigned int i;
	i = [imageList indexOf: currentTeX];
	if(i>=([imageList count]-1)) {
		return self;
	};
	i++;
	[self newTeXitem: [imageList objectAt: i]];
	return self;
}

- down: sender
{
	unsigned int i;
	i = [imageList indexOf: currentTeX];
	if(i==0) {
		return self;
	}
	i--;
	[self newTeXitem: [imageList objectAt: i]];
	return self;
}

- insert: sender
{
	id newTeX;
	unsigned int i;

	newTeX = [[TeXitem alloc] init];
	[[newTeX text: NULL] image: nil];
	
	i = [imageList indexOf: currentTeX];
	if(i==NX_NOT_IN_LIST) i=0;
	[imageList insertObject: newTeX at: i]; // insert at the spot
	[self newTeXitem: newTeX];
	return self;
}


- info:sender
{
	if(!infoPanel) {
		[NXApp loadNibSection: "Info.nib" owner:self];
	}
	[infoPanel makeKeyAndOrderFront: self];
	return self;
}



- open: sender
{
	id openPanel=[OpenPanel new];
	const char *newfilename;
	const char *types[]={"texfig",NULL};

	[openPanel allowMultipleFiles: NO];
	if([openPanel runModalForTypes: types] && (newfilename = [openPanel filename])) {
		if(![self openFile:newfilename])
			NXRunAlertPanel("Open Error","Can't open file %s for reading",
				"Continue",NULL,NULL,filename);

	}
	return self; 
}


- (BOOL)openFile:(const char*)pathname
{
	NXTypedStream *typedStream;

	strcpy(filename,pathname);
	if(!(typedStream=NXOpenTypedStreamForFile(pathname,NX_READONLY))) {
				return NO;
	}		
	if(imageList!=nil) [imageList free];
	imageList = NXReadObject(typedStream);
	if([imageList count]==0) [self insert: self];
	else [self newTeXitem:[imageList objectAt: 0]];
	[[imageView window] setTitleAsFilename:pathname];
	return YES;
}

- save: sender
{
	NXTypedStream *typedStream;

	if(!strlen(filename)) [self saveAs:self];

	if(!(typedStream = NXOpenTypedStreamForFile(filename,NX_WRITEONLY))) {
		NXRunAlertPanel("Save Error","Cannot open file %s for writing",
			"Continue",NULL,NULL,filename);
		return self;
	}
	NXWriteObject(typedStream,imageList);
	NXCloseTypedStream(typedStream);
	return self;
}

- saveAs:sender
{
	id savePanel=[SavePanel new];

	[savePanel setRequiredFileType: "texfig"];
	if([savePanel runModal]) {
		strcpy(filename,[savePanel filename]);
		[[imageView window] setTitleAsFilename:filename];
		[self save:self];
	}
	return self;
}


- preferences: sender
{
	if(!prefPanel) {
		[NXApp loadNibSection: "Preferences.nib" owner:self];
	}
	[prefPanel makeKeyAndOrderFront: self];
	return self;


	return self;
}


- (int)app:sender openFile:(const char *)newfilename type:(const char *)aType
{
	BOOL reply;
	reply =  [self openFile:newfilename];
	return (int)reply;
}

- (BOOL)appAcceptsAnotherFile:sender
{
	return YES;
}

@end

