#import "BriefDoc.h"
#import "Briefcase.h"
#import <appkit/appkit.h>
#import "Global.h"

@implementation BriefDoc: MultDoc

/* Canon Information Systems is not responsible for anything anyone does with this   */
/* code, nor are they responsible for the correctness of this code.  Basically, this */
/* has very little to do with the company I work for, and you can't blame them.      */

/* This file is best read in a window as wide as this comment, and with tab settings */
/* of 4 spaces and indent setting of 4 spaces (at least, that's what I use).		 */

/* You are welcome to do as you would with this file under the following conditions. */
/* First, I accept no blame for anything that goes wrong no matter how you use it,   */
/* no matter how catastrophic, not even if it stems from a bug in my code.			 */
/* Second, please keep my notices on it when/if you distribute it.					 */
/* Third, if you discover any bugs or have any comments, PLEASE TELL ME!  Code won't */
/* get better without people picking it apart and giving the writer feedback.        */
/* Fourth, if you modify it, please keep a notice that your version is based on mine */
/* in the source files (and keep the notice that mine is based on four other pieces  */
/* of code :<).  Thanks, and have fun.  - Subrata Sircar, ssircar@canon.com			 */

/* Version 0.9b		Apr-19-92		First Public Release	*/
/* Version 0.95		Apr-29-92		Bug Fixes				*/
/* Version 1.0b		Aug-08-92		Minor Bug Fixes			*/

/* New creation methods */

+ initialize
/* Class variable initialization.  DO NOT call from subclasses. */
{
    if (self == [BriefDoc class]) {
		[self setVersion:100];
		[self setExtension:LocalString("bc")];
		[self setDefault:LocalString("Untitled%d")];
	}
	return self;
}

+ newFromFile:(const char *)file
{
    NXStream *stream;
    id text;
	int count;
	char tempBuf[8192], fileBuf[16384], *tempPtr, *lastPtr;
	
    stream = NXMapFile(file,NX_READONLY);
    if (stream) {
    	self = [[self class] new];
		text = [view docView];
		[window disableDisplay];
		[text readText:stream];
		[text selectAll:self];
		count = [text textLength];
		[text getSubstring:tempBuf start:0 length:count];
		tempPtr = lastPtr = tempBuf;
		*fileBuf = '\0';
		while (tempPtr = index(tempPtr,'/')) {
			if (*(++tempPtr) == '*') {
				lastPtr = ++tempPtr;
				tempPtr = index(tempPtr,'*');
				count = (int)(tempPtr-lastPtr);
				strncat(fileBuf,lastPtr,count);
				strcat(fileBuf,"\n");
				tempPtr += 2;
			}
    	}
		[text selectAll:self];
		[text replaceSel:fileBuf];
		[text sizeToFit];
		[self setName:file];
		NXCloseMemory(stream,NX_FREEBUFFER);
		[self setSavedDocument:YES];
		[self setEmpty:NO];
		[window reenableDisplay];
		[window display];
		[window makeKeyAndOrderFront:self];
		return self;
    } else {
		Notify(LocalString("BriefDoc: can't open file"),file);
		return nil;
    }
}

- setUpNib
{
	LoadLocalNib(LocalString("BriefDoc.nib"),self,NO,MyZone);
    [[view docView] setDelegate:self];
    [window makeFirstResponder:[view docView]];
	return self;
}

- addFiles:(char *)fileList
{
	int length = 0;
	
	id text = [view docView];
	length = [text textLength];
	[text setSel:length :length];
	[text replaceSel:fileList];
	[[text window] display];
	/* hack to keep status correct - text object doesn't tell me when this happens */
	if (fileList && *fileList) {
		[self dirty:YES];
		[self setEmpty:NO];
	}
	return self;
}

/* Methods related to naming/saving this document. */

- (const char *)_cname
/*
 * Returns a fully specified file name with ".c" extension.
 */
{
    char *ext;
    static char textnamebuf[MAXPATHLEN+1];

    sprintf(textnamebuf,[self fileName]);
    ext = rindex(textnamebuf,'.');
    *(ext++) = '.';
    *(ext++) = 'c';
    *ext = '\0'; 
    return textnamebuf;
}

- (const char *)_execname
/*
 * Returns a fully specified file name with no extension.
 */
{
    char *ext;
    static char execnamebuf[MAXPATHLEN+1];

    sprintf(execnamebuf,[self fileName]);
    ext = rindex(execnamebuf,'.');
    *ext = '\0'; 
    return execnamebuf;
}

- save
{	
    NXStream *ts = NULL;
    int fd = 0;
    
    fd = open([self fileName], O_CREAT | O_WRONLY | O_TRUNC, 0644);
    ts = NXOpenFile(fd, NX_WRITEONLY);
    if (ts) {
		id text = [view docView];
		int count = [text textLength];
		char tempBuf[count + 8192];
		char fileBuf[count + 8192];
		char quoteBuf[3];
		char *tempPtr, *lastPtr;
		const char *fn = [self fileName], *en = [self _execname], *cn = [self _cname];
		char quote = '"';

		sprintf(quoteBuf,"%c",quote);
		[window disableDisplay];
		[text selectAll:self];
		[text getSubstring:tempBuf start:0 length:count];
		tempPtr = lastPtr = tempBuf;
		*fileBuf = '\0';
		while (tempPtr = index(tempPtr,'\n')) {
			count = (int)(tempPtr-lastPtr);
			strcat(fileBuf,"/*");
			strncat(fileBuf,lastPtr,count);
			strcat(fileBuf,"*/\n");
			tempPtr++;
			lastPtr=tempPtr;
    	}
		tempPtr = lastPtr = tempBuf;
		strcat(fileBuf,"#include <stdlib.h>\n\n");
		strcat(fileBuf,"main()\n{\nsystem(");
		strcat(fileBuf,quoteBuf);
		strcat(fileBuf,"open ");
		while (tempPtr = index(tempPtr,'\n')) {
			count = (int)(tempPtr-lastPtr);
			strncat(fileBuf,lastPtr,count);
			strcat(fileBuf," ");
			tempPtr++;
			lastPtr=tempPtr;
    	}
		tempPtr = rindex(fileBuf,' ');
		*tempPtr = '\0';
		strcat(fileBuf,quoteBuf);
		strcat(fileBuf,");\n}\n");
		[text replaceSel:fileBuf];
		[text writeText:ts];
		NXFlush(ts);
		NXClose(ts);
		[text selectAll:self];
		[text replaceSel:tempBuf];
		*tempBuf = '\0';
		sprintf(tempBuf,"mv %s %s",fn,cn);
		system(tempBuf);
		*tempBuf = '\0';
		sprintf(tempBuf,"cc -O -o %s %s",en,cn);
		system(tempBuf);
		*tempBuf = '\0';
		sprintf(tempBuf,"strip %s",en);
		system(tempBuf);
		*tempBuf = '\0';
		sprintf(tempBuf,"mv %s %s",cn,fn);
		system(tempBuf);
		[window reenableDisplay];
		[self dirty:NO];
		[self setSavedDocument:YES];
    } else Notify(LocalString("BriefDoc: save - Unable to create file "),[self fileName]);
    close(fd);
    return self;
}

/* Text Delegate methods */

- textDidGetKeys:sender isEmpty:(BOOL)flag
{
	[self dirty:YES];
	[self setEmpty:flag];
	return self;
}

@end
