//
// WeekWindow.m
// Copyright (c) 1989, 1990,  1991 by Jiro Nakamura 
// All rights reserved
//
//	by Jiro Nakamura (jiro@shaman.com)
//
// RCS Information
// Revision Number->	$Revision: 1.3 $
// Last Revised->	$Date: 91/02/17 22:03:21 $
//
static char rcsid[] = "$Id: WeekWindow.m,v 1.3 91/02/17 22:03:21 jiro Exp Locker: jiro $";

#import "Global.h"
#import "Event.h"
#import "cass.h"	// for TODAYICON
#import "calendar.h"	// for ascMyDate()
#import <appkit/Application.h>		// For NXApp 
#import <appkit/ScrollView.h>
#import <appkit/Text.h>
#import <appkit/TextField.h>
#import <appkit/PopUpList.h>
#import <appkit/Matrix.h>
#import "WeekWindow.h"

#import <sys/file.h>
#import <libc.h>
#import <strings.h>



// The minimum dimensions of the week window
#define MIN_WIDTH		870.0
#define MIN_HEIGHT		100.0


@implementation WeekWindow

- open:sender
{
	static alreadyInited = FALSE;
	
	if( !alreadyInited)
		{
		char	dumbChar[5];
		
		// dumb references to some static constants, just
		// to avoid warning messages from the compiler (Garance)
		dumbChar[0] = rcsid[0];		// dumb de dumb

		alreadyInited = TRUE;
		[self placeWindow: [global weekFrame]];
		thisWeek = *timeNow();
		thisWeek.tm_mday -= thisWeek.tm_wday;
		thisWeek.tm_hour = thisWeek.tm_min = thisWeek.tm_sec = 0;
		fixTmStructure( &thisWeek);
		#ifdef DEBUG
			fprintf(stderr,"This week is: %s", 
				ascMyDate(&thisWeek));
		#endif
		priorityCutOff = [global lowPriority];
		[self	setDelegate: self];
	
		mondayView = [mondayScroll docView];
		tuesdayView = [tuesdayScroll docView];
		wednesdayView = [wednesdayScroll docView];
		thursdayView = [thursdayScroll docView];
		fridayView = [fridayScroll docView];
		saturdayView = [saturdayScroll docView];
		sundayView = [sundayScroll docView];
	
		[mondayView setMonoFont: FALSE];
		[tuesdayView setMonoFont: FALSE];
		[wednesdayView setMonoFont: FALSE];
		[thursdayView setMonoFont: FALSE];
		[fridayView setMonoFont: FALSE];
		[saturdayView setMonoFont: FALSE];
		[sundayView setMonoFont: FALSE];

		[mondayView setEditable: FALSE];
		[tuesdayView setEditable: FALSE];
		[wednesdayView setEditable: FALSE];
		[thursdayView setEditable: FALSE];
		[fridayView setEditable: FALSE];
		[saturdayView setEditable: FALSE];
		[sundayView setEditable: FALSE];

		[self setMiniwindowIcon: 	WEEKICON];
		
		viewPopUp = 		[PopUpList new];
		[viewPopUp	addItem:	"View All"];
		[viewPopUp	addItem:	"View Mid~High"];
		[viewPopUp	addItem:	"View Only High"];
		[[viewPopUp itemList] selectCellAt:1:0];
		NXAttachPopUpList(viewPopUpButton, viewPopUp);
		}
	[self	makeKeyAndOrderFront: self];
	[self	update];	// this will cause an update
	return self;
}

- save
{
	// This window shouldn't save itself. 
	return self;
}

- close
{
	[global	saveThisWindowPosition:	DEFAULTWEEKFRAME : self];
	[super close];
	miniaturized = FALSE;
	return self;
}

- update
{
	struct tm tempDay;
	char temp[80];
	extern const char *shortMonths[12];
	int tmp;
	
	fixTmStructure( &thisWeek );
	tempDay = thisWeek;
	
	if( miniaturized || ![self isVisible])
		return self;
	
	sprintf(temp, "Week of: %s %d, %d", 
		shortMonths[tempDay.tm_mon], tempDay.tm_mday,
		tempDay.tm_year + 1900);
	
	[weekTextField setStringValue:	temp];	
	tmp = [self	updateView:  sundayView on: &tempDay fromEvent: 0];
	tempDay.tm_mday ++;
	tmp = [self	updateView:  mondayView on: &tempDay 
		fromEvent: tmp];
	tempDay.tm_mday ++;
	tmp = [self	updateView:  tuesdayView on: &tempDay 
		fromEvent: tmp];
	tempDay.tm_mday ++;
	tmp = [self	updateView:  wednesdayView on: &tempDay
		fromEvent: tmp];
	tempDay.tm_mday ++;
	tmp = [self	updateView:  thursdayView on: &tempDay
		fromEvent: tmp];
	tempDay.tm_mday ++;
	tmp = [self	updateView:  fridayView on: &tempDay
		fromEvent: tmp];
	tempDay.tm_mday ++;
	[self	updateView:  saturdayView on: &tempDay fromEvent: tmp];	
	return self;
}

- (int) updateView: (id) dayView on: (struct tm *) thisDay fromEvent: (int) en
{
	NXStream *output; 
	Event *ev;
	int eventCount;
	int today, temp;
	extern const char *shortMonths[12], *shortWeekDays[7];

	fixTmStructure( thisDay );

	// We want to read the eventFile pointed to by global 
	ev = [Event newAt:[global eventFile]];

	// We need a temporary memory stream to store the queue.
	if( (output = NXOpenMemory( NULL, 0, NX_READWRITE)) == NULL)
		{
		fprintf(stderr,"%s: Couldn't open memory stream for "
			"Week Window queue scrollview. FATAL ERRROR.\n",
			PROGNAME);
		exit(1) ;
		}
		
	if( en != 0)		
		[ev readEvent: en];
	else
		[ev firstEvent];
					
	today = [ev mday];
	
	if( dayCompare( thisDay, (struct tm *) timeNow()) == -1)
		today = -2;		
	else
		{		
		while( [ev present] != 0 &&
			dayCompare( [ev time], thisDay ) == -1 )
			[ev readEvent : [ev next]]; 	

		if( ([ev mday] != thisDay->tm_mday) || 
			([ev mon]  != thisDay->tm_mon) || 
			([ev year] != thisDay->tm_year))
		    	today = -1;
		else	
			today = [ev mday];
		}
		
	NXPrintf(output, "{\\rtf0\\ansi{\\fonttbl\\f0\\fmodern "
		"%s;}\\fs%.0f\n",
		[global fontName], [global fontSize] * 2);

	NXPrintf(output, "{\\f0\\b %s %s %2d\\par}\n", 
		shortWeekDays[thisDay->tm_wday],
		shortMonths[thisDay->tm_mon], thisDay->tm_mday);

	eventCount = 0;
				
	/* Print all events for today regardless of priority */
	while ( [ev present] != 0 && [ev mday] == today)
		{
		if( [ev priority] < priorityCutOff)
			{
			[ev readEvent : [ev next]]; 	
			eventCount++;
			continue;
			}
			
		if( [ev priority] > [global highPriority])
			NXPrintf(output, "{\\f0\\b ");
		else
			NXPrintf(output, "{\\f0 ");

		if( [global militaryTime])
			NXPrintf(output, "\\par {\\f0\\b %2d:%02d}"
				"{\\par \\li360 %s\\par}}\n", 
				[ev hour], [ev min], [ev message]);
		else
			{
			temp = [ev hour];
			if( temp > 12 ) temp -= 12;
			if( temp == 0 ) temp = 12;			
			NXPrintf(output, "\\par{\\f0\\b %2d:%02d %s}"
				"{\\par \\li360 %s\\par}}\n", 
					temp,	[ev min], 
					([ev hour]>11)?"pm":"am", 
					[ev message]);
			}
		[ev readEvent : [ev next]]; 	
		}   

	if( [ev present] == 0 || today <  0)
		{
		if( today == -2)
			NXPrintf(output,  "{\\f0\\par Ancient history.}\n");
		else
			NXPrintf(output, "{\\f0\\par No events.}\n");
		}
	
	if( eventCount > 0)	// Number of invisible events
		{
		NXPrintf(output, "{\\par (%d hidden)\\par}\n", 
					eventCount);
		}
					
	NXPrintf(output, "}\n");	

	NXSeek(output, 0, NX_FROMSTART);
	[dayView readRichText: output]; 
	NXCloseMemory(output, NX_FREEBUFFER); 
	
	[dayView hideCaret];	// for some reason the Text
	
	temp = [ev present];
	[ev free];			
	return temp;
}

- weekBefore:sender
{		
	if( ([NXApp currentEvent]->flags) & NX_ALTERNATEMASK)
		thisWeek.tm_mday -= 1;
	else		
		thisWeek.tm_mday -= 7;		
	[self update];
	return self;
}

- weekAfter:sender
{
	if( ([NXApp currentEvent]->flags) & NX_ALTERNATEMASK)
		thisWeek.tm_mday += 1;
	else
		thisWeek.tm_mday += 7;
	[self update];
	return self;
}

- weekNow:sender
{
	thisWeek = *timeNow();
	thisWeek.tm_mday -= thisWeek.tm_wday;
	thisWeek.tm_hour = thisWeek.tm_min = thisWeek.tm_sec = 0;
	fixTmStructure( &thisWeek);
	[self update];
	return self;
}


- viewPopUpChanged:sender
{	
	switch( [[viewPopUp itemList] selectedRow])
		{
		case 2:
			priorityCutOff = [global highPriority];
			break;
		case 1:
			priorityCutOff = [global lowPriority];
			break;
		case 0:
		default:
			priorityCutOff = 0;
			break;
		}
	#ifdef DEBUG
		fprintf(stderr, "Priority changed to %d.... (tag = %d)\n",
		 	priorityCutOff, [[viewPopUp itemList] selectedRow]);
	#endif
	[self update];
	return self;
}

- windowDidMiniaturize: sender
{
	#ifdef DEBUG
		fprintf(stderr,"Today did miniaturize\n");
	#endif

	miniaturized = TRUE;
	minute = -1;		// Force a redisplay on reopening
	return self;
}

- windowDidDeminiaturize: sender
{
	#ifdef DEBUG
		fprintf(stderr,"Today did deminiaturize\n");
	#endif

	miniaturized = FALSE;
	minute = -1;		// Force a redisplay
	[self update];
	return self;
}

- defaultsDidChange: sender
{
	#ifdef DEBUG
		fprintf(stderr,"Defaults changed.... Week win compensating\n");
	#endif
	
	militaryTime 	= [global militaryTime];
	[self update];
	return self;
}



- windowWillResize: (id) sender toSize: (NXSize *) size
{
	#ifdef DEBUG
		fprintf(stderr,"Window would have resized to %f x %f.\n", 
			size->width, size->height);
	#endif
	
	size->width = MIN_WIDTH;	// can't change the width, ever
	if( size->height < MIN_HEIGHT)
		size->height = MIN_HEIGHT;
		
	#ifdef DEBUG
		fprintf(stderr,"Window will resize to %f x %f.\n", 
			size->width, size->height);
	#endif
	return self;
}
@end
