
/*  Document.m written by Robert Vasvari, Oct 1994.
	This class is a generic document that has its own nibfile.
	The Document object comes with: name,path and window. Also,
	it implements some of the most basic document handling
	methods that most apps need.
 */
#import "Document.h"
#import "MenuController.h"
#import "util.h"
#import "defs.h"

@implementation Document

/* ==== init section ==== */

- init
{	[super init];
	[NXApp  loadNibSection:"Document.nib" owner:self withNames:NO
		fromZone:(NXZone *)[self zone]];
	return self;
}

- awakeFromNib
{	
	createTime=time(0);
	lastModifyTime=createTime;
	return self;
}

/* ==== access to instance variables ==== */

- window
{	return window;
}

- (int)tag
{	return tag;
}

- setTag:(int)aTag
{	tag=aTag;
	return self;
}

- (const char *)documentName
{	return documentName;
}

- (const char *)documentPath
{	return documentPath;
}

- setDocumentName:(const char *)aName
{	copyStringBufferFromZone(&documentName,aName,[self zone]);
	return self;
}

- setDocumentPath:(const char *)aPath
{	copyStringBufferFromZone(&documentPath,aPath,[self zone]);
	return self;
}

- getInspectorData:(const char **)nm :(const char **)pth :(int *)t
		:(unsigned long *)ct :(unsigned long *)lt
{
	if(nm) *nm=documentName;
	if(pth) *pth=documentPath;
	if(t) *t=tag;
	if(ct) *ct=createTime;
	if(lt) *lt=lastModifyTime;
	return self;
}

/* ==== file handling ==== */

- setupNewDoc:(const char *)newPath
{
const char *p=getDefaultWithErrorCheck("WindowSize");
int winWidth, winHeight;

	time(&createTime);
	lastModifyTime=createTime;
	[self setDocumentPath:newPath];
	[self setDocumentName:findNameInPath(newPath)];
	
	/* set the window size according to the default */
	if(p)
	 { sscanf(p,"%d %d", &winWidth, &winHeight);
	   [window sizeWindow:(NXCoord)winWidth :(NXCoord)winHeight];
	   [window setTitleAsFilename:documentPath];
	 }
	[window makeKeyAndOrderFront:nil];
	return self;
}

- (BOOL)openDocFile:(const char *)aPath
{
NXStream *st;
NXRect r;
int scrNum;

	/* initialize all instance variables */
	[self setDocumentPath:aPath];
	st=NXMapFile(aPath, NX_READONLY);

	NXScanf(st,"Window Frame: %f %f %f %f\n",&r.origin.x,
	   				&r.origin.y,&r.size.width,&r.size.height);
	NXScanf(st,"Screen Number: %d\n",&scrNum);
	NXScanf(st,"Created: %d",&createTime);
	NXScanf(st,"Modified: %d",&lastModifyTime);
	
	[self setDocumentName:findNameInPath(aPath)];
	[window placeWindow:&r screen:getScreenOfNumber(scrNum)];
	[window setTitleAsFilename:documentPath];
	[window makeKeyAndOrderFront:nil];
	return YES;
}

- saveDocument
{	[self saveDocumentTo:documentPath];
	return self;
}

- saveDocumentAs:(const char *)aPath
{	
	copyStringBufferFromZone(&documentPath, aPath, [self zone]);
	[self setDocumentName:findNameInPath(aPath)];
	[self saveDocumentTo:documentPath];
	[window setTitleAsFilename:documentPath];
	return self;
}

- saveDocumentTo:(const char *)aPath 
{	
NXStream *st;
NXRect r;
NXScreen *scr;

	[window getFrame:&r andScreen:&scr];
	if((st=NXOpenMemory(NULL, 0, NX_WRITEONLY))==NULL)
	 { NXRunAlertPanel("Error","Could not open stream for file %s",
	    NULL,NULL,NULL, aPath);
	    return self;
	 }

	NXPrintf(st,"Window Frame: %d. %d. %d. %d.\n",(int)NX_X(&r),
	   (int)NX_Y(&r),(int)NX_WIDTH(&r),(int)NX_HEIGHT(&r));
	NXPrintf(st,"Screen Number: %d\n",scr->screenNumber);
	NXPrintf(st,"Created: %d\n",createTime);
	NXPrintf(st,"Modified: %d\n", lastModifyTime);
	
	NXSaveToFile(st, aPath);
	NXCloseMemory(st, NX_FREEBUFFER);

	[NXApp perform:@selector(updateWindows) with:nil
	   afterDelay:1 cancelPrevious:YES];

	return self;
}

/* ==== Window delegate methods ==== */

- windowDidBecomeKey:sender
{
	[[NXApp delegate] setCurrentDoc:self];
	[NXApp perform:@selector(updateWindows) with:nil
	   afterDelay:100 cancelPrevious:YES];
	return self;
}

- windowWillClose:sender
{
	if([window isDocEdited])
	 { switch(NXRunAlertPanel("Close",
	    "Save changes to %s",
		"Save", "Do not save", "Cancel",documentName))
	    { case NX_ALERTDEFAULT:[self saveDocument]; break;
		  case NX_ALERTALTERNATE: break;
		  case NX_ALERTOTHER: return nil;
		}
	 }
	[[NXApp delegate] perform:@selector(freeDoc:) with:self
	  afterDelay:1 cancelPrevious:YES];
	return self;
}

- windowDidResize:sender
{	[NXApp perform:@selector(updateWindows) with:nil
	   afterDelay:1 cancelPrevious:YES];
	return self;
}

- windowDidUpdate:sender
{
	/* if you have buttons in the window, enable/disable
	   them here
	 */
	return self;
}

/* ==== Edit methods ==== */

- delete:sender
{   
	if(![[NXApp delegate] isDeleteEnabled]) return self;
	if(NXRunAlertPanel("Are you sure to delete ?",
	"This operation is not reversable",
	"Do not delete","Delete All",NULL)==NX_ALERTDEFAULT) return self;

	[window disableFlushWindow];

	/* do deletion here */
	
	[window reenableFlushWindow];
	[window flushWindow];
	[NXApp perform:@selector(updateWindows) with:nil
	   afterDelay:1 cancelPrevious:YES];
	return self;
}

- selectAll:sender
{
	[window disableFlushWindow];

	/* do selection here */
	
	[window reenableFlushWindow];
	[window flushWindow];
	[NXApp perform:@selector(updateWindows) with:nil
	   afterDelay:1 cancelPrevious:YES];
	return self;
}

- free
{	
NXZone *z=[self zone];	
	if(window) [window free];
	if(documentPath) free((char *)documentPath);
	if(documentName) free((char *)documentName);
	[super free];
	
	/* sanity check */
	if(z!=[NXApp zone]) NXDestroyZone(z);
	return nil;
}

@end
