
#import "STDocumentClass.h"
#import "STAppController.h"
#import "STMenuCategory.h"
#import "STUtil.h"
#import "STDefines.h"

@implementation STDocumentClass

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

+ newDocument
{	
	/* return a newly allocated, autoreleased object */
	id newDoc=[[self alloc] init];
	return [newDoc autorelease];
}

- (NSString *)nibName
{	return @"Document.nib";
}
	
- init
{	
	[super init];
	[NXApp  loadNibSection:[[self nibName] cString] owner:self withNames:NO
		fromZone:(NXZone *)[self zone]];
	createTime=(NSCalendarDate *)[[NSCalendarDate date] retain];
	lastModifyTime=[createTime copy];
	
	return self;
}

- awakeFromNib
{	return self;
}

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

- window
{	return window;
}

- (int)tag
{	return tag;
}

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

- (NSString *)documentName
{	return documentName;
}

- (NSString *)documentPath
{	return documentPath;
}

- setDocumentName:(NSString *)aName
{	
	if(documentName) [documentName autorelease];
	documentName=[aName copyWithZone:[self zone]];
	
	return self;
}

- setDocumentPath:(NSString *)aPath
{	
	if(documentPath) [documentPath autorelease];
	documentPath=[aPath copyWithZone:[self zone]];
	if(window) [window setTitleAsFilename:[documentPath cString]];
	return self;
}

- getInspectorData:(NSString **)nm :(NSString **)pth :(int *)t
		:(NSCalendarDate **)ct :(NSCalendarDate **)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 ==== */


- (BOOL)openDocumentFile:(NSString *)aPath
{
NXStream *st;

	/* initialize all instance variables */
	[self setDocumentPath:aPath];
	[self setDocumentName:[aPath lastPathComponent]];

	st=NXMapFile([aPath cString], NX_READONLY);
	if(!st)
	 {	NXRunAlertPanel("Error","Document %s does not exist!",
	     NULL,NULL,NULL,aPath);
		return NO;
	 }
	[self readAttributes:st];
	
	[window setTitleAsFilename:[documentPath cString]];
	return YES;
}

- readAttributes:(NXStream *)st
{
char buf[BUFSIZE]="";
NXRect r;
int scrNum;
	NXScanf(st,"Window Frame: %f %f %f %f\n",&r.origin.x,
	   				&r.origin.y,&r.size.width,&r.size.height);
	[window placeWindow:&r screen:getScreenOfNumber(scrNum)];
	NXScanf(st,"Screen Number: %d\n",&scrNum);
	NXScanf(st,"Created: \"");
	NXGets(st, buf,BUFSIZE);
	createTime=[[NSCalendarDate allocWithZone:
				[self zone]] initWithString:[NSString stringWithCString:buf]
				 	calendarFormat:INTLDATEFORMAT];
	NXScanf(st,"Modified: \"");
	NXGets(st, buf,BUFSIZE);
	lastModifyTime=[[NSCalendarDate allocWithZone:
				[self zone]] initWithString:[NSString stringWithCString:buf]
				 	calendarFormat:INTLDATEFORMAT];
	return self;
}

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

- saveDocumentAs:(NSString *)aPath
{	
	[self saveDocumentTo:aPath];
	[window setTitleAsFilename:[documentPath cString]];
	return self;
}

- saveDocumentTo:(NSString *)aPath 
{	
NXStream *st;

	[self documentModified:self];
	[self setDocumentPath:aPath];
	[self setDocumentName:[aPath lastPathComponent]];
	if((st=NXOpenMemory(NULL, 0, NX_WRITEONLY))==NULL)
	 { NXRunAlertPanel("Error","Could not open stream for file %s",
	    NULL,NULL,NULL, aPath);
	    return self;
	 }

	[self writeAttributes:st];

	NXSaveToFile(st, [aPath cString]);
	NXCloseMemory(st, NX_FREEBUFFER);

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

	return self;
}

- writeAttributes:(NXStream *)st
{
NXRect r;
NXScreen *scr;
	[window getFrame:&r andScreen:&scr];
	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: \"%s\"\n",
		[[createTime 
			descriptionWithCalendarFormat:INTLDATEFORMAT] cString]);
	NXPrintf(st,"Modified: \"%s\"\n",
		[[lastModifyTime 
			descriptionWithCalendarFormat:INTLDATEFORMAT] cString]);
	return self;
}

- documentModified:sender
{	[lastModifyTime release];
	lastModifyTime=(NSCalendarDate *)[[NSCalendarDate date] retain];
	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;
}


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


@end
