/*
 * $Source: $
 * $Revision: $
 * $Date: $
 * $State: $
 * $Author: $
 *
 *
 * $Log: $
 * Version 3.1	4/10/92 wade
 * Added print_getinfo()
 *
 */

/*  Copyright (c) 1991 by the Massachusetts Institute of Technology,
 *	For copying and distribution information, see the file
 *	"mit-copyright.h".
 *
 * 	printMgr.c 
 *		Printer commands.
 *
 *	print_page_dlog
 *	print_cmd
 *	print_text
 *	print_list
 *  print_getinfo
 *  print_header
 *  need_page
 *
 */

#include <Types.h>
#include <Quickdraw.h>
#include <Windows.h>
#include <Fonts.h>
#include <TextEdit.h>
#include <Menus.h>
#include <String.h>
#include <Memory.h>
#include <Packages.h>
#include <files.h>
#include <Lists.h>
#include <Sysequ.h>
#include <stdio.h>
#include <Printing.h>
#include <Time.h>
#include <Resources.h>
#include <ToolUtils.h>
#include "prototype.h"
#include "pips.h"
#include "mit-copyright.h"

#define bDevCItoh 1
#define ICN				1229147683

THPrint print_handle = NULL;

static TPPrPort pport;				/* Printer port */
static TPrStatus tstatus;			/* return value of PrPicFile */
static short num_lines = -1;		/* Number of lines so far */
static short pline_height;			/* Height of normal text */
static char p_from[40],p_date[40];	/* From & Date */
static char p_subject[60];			/* Subject */
static short page_num;				/* Page num */
static short page_y;				/* Y coord. on page */

extern WindowPtr	gListWindow;
extern WindowPtr	gTextWindow;

#pragma segment Print
print_page_dlog()
{
     if (print_handle == NULL) {
	  PrOpen();
	  print_handle = (THPrint) NewHandle(sizeof(TPrint));
	  PrintDefault(print_handle);
     }

     PrStlDialog (print_handle);
}

#pragma segment Print
print_cmd()
{
     WindowPtr window;
     FontInfo  finfo;
	 
	 window = FrontWindow();
	
     if (print_handle == NULL) {
	  PrOpen();
	  print_handle = (THPrint) NewHandle(sizeof(TPrint));
	  PrintDefault(print_handle);
     }
	 
     if (!PrJobDialog (print_handle)) {
     	return;
	 }
	 if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"Job Dialog");
		
     pport = PrOpenDoc(print_handle, nil, nil);
	 if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"PrOpenDoc");
		
     if (((((**print_handle).prStl.wDev) >> 8) & 0xFF) == bDevCItoh)
	    TextFont(monaco);
     else
	    TextFont(courier);
	  
     TextSize (12);
     GetFontInfo(&finfo);
     pline_height = finfo.ascent + finfo.descent + finfo.leading;

     num_lines = -1;

	 switch(wind_type(window)) {
	 	case text:	
	 		print_text(window);
			break;
		case list:
	 		print_list(window); 
			break;
		case getinfo:
			print_getinfo(window);
			break;
		default:
			OpenAlertDialog(PRINT_ERROR,"Could not print the front most window.");
	}

     PrCloseDoc(pport);
		
     if ((**print_handle).prJob.bJDocLoop == bSpoolLoop && PrError() == noErr) {
          PrPicFile(print_handle,nil,nil,nil,&tstatus);
	 }
	 
     if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"PrPicFile");
}

#pragma segment Print
print_text(window)
WindowPtr	window;
{
	Str255	title;
	Str255	menu;
	time_t	seconds;
	Handle	text_handle;
	int		text_length;
	char	*start;
	char	*end;
	short	x;
	char	buf[512];
	char	*dp;
	Rect	page_rect;
	short	c_width;
	short	num_spaces;
	char	*orig_dp;
	char	*orig_sp;
	char	*tp;
	short	i;
	short	ctr;
	
     /* Figure out page headers */
     p_date[0] = '\0';
     p_from[0] = '\0';
     p_subject[0] = '\0';
     page_num = 0;
		
	 GetWTitle(window, title );
	 p2cstr(title);
	 strncpy(p_subject, title, sizeof(p_subject));
	 p_subject[sizeof(p_subject)-1] = '\0';				/* make sure there is an ending null char */
	 
	 GetWTitle(gListWindow, menu );
	 p2cstr(menu);
	 /* get rid of the # items, ie. "(n items)" from the menu title */
	 for (tp = &menu[strlen(menu) - 1]; *tp != '('; tp-- );
	 if (*tp == '(')
	 	*tp = '\0';
	 strncpy(p_from, menu, sizeof(p_from));
	 p_from[sizeof(p_from)-1] = '\0';
	 if (strlen(menu) >= sizeof(p_from)-1) {
	 	ctr = 3;
	 	for(tp=&p_from[sizeof(p_from)-2];ctr>0;ctr--,tp--)
			*tp = '.';
	 }
	 
	 time(&seconds);
	 strncpy(p_date, ctime(&seconds), sizeof(p_date));
	 p_date[sizeof(p_date)-1] = '\0';
	 tp = strstr(p_date,"\n");
	 if ( tp != NULL )
	 	*tp = '\0';
		
	 PrOpenPage(pport, nil);
	 if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"PrOpenPage");
	 print_header();
	 
	 text_handle = text_get_handle(window);
	 text_length = text_get_length(window);
	 HLock(text_handle);
	 
	 page_rect = (**print_handle).prInfo.rPage;
	 c_width = CharWidth('m');
	 
	 start = *text_handle;
	 end = start + text_length;
	 while( start < end ) {
	 	if (need_page()) {
			if (num_lines != -1) {
				PrClosePage(pport);
				if (PrError() != noErr)
	 				OpenAlertDialog(PRINT_ERROR,"PrClosePage");
			}
			PrOpenPage(pport,nil);
			if (PrError() != noErr)
	 			OpenAlertDialog(PRINT_ERROR,"PrOpenPage");
			print_header();
		}
		
		dp = buf;
		x = page_rect.left + 5;
		while( start < end && *start != '\n') {
		 	if (*start == '\t') {
		    	num_spaces = 8 - ((dp - buf) % 8);
		    	for (i = 0; i < num_spaces; i++)
			 		*dp++ = ' ';
		    		start++;
	       	}
			else
		    	*dp++ = *start++;
			
			if (x + (dp - buf) * c_width > page_rect.right) {
		    	orig_dp = dp-1;
		    	orig_sp = start-1;
		    	while(dp > buf && !(isspace(*(dp - 1)))) {
		         	dp--;
			 		start--;
		    	}
				
	            if (dp == buf) {
		          dp = orig_dp;
			 	  start = orig_sp;
		    	}
				
		    	while(dp > buf && isspace(*(dp - 1)))
			 		dp--;
					
		    	while(start < end && (*start == ' ' || *start == '\t'))
			 		start++;
		    	break;
	       }
			
		}
		
		if (start < end && *start == '\n' )
			start++;
		
		MoveTo(x, page_y);
		DrawText(buf,0,dp-buf);
		page_y += pline_height;
		num_lines++;
	 }
	 
	 HUnlock(text_handle);
	 PrClosePage(pport);
}

#define print_label(a1,a2) { \
	page_y += pline_height; \
	TextFace(bold); \
	MoveTo(x, page_y); \
	DrawText(a1,0,a2); \
	TextFace(normal); \
}

#define print_info(b1,b2) { \
	MoveTo(t, page_y); \
	DrawText(b1,0,b2); \
	page_y += pline_height; \
}
/*
 *	print_getinfo print the contents in the getinfo window.
 *  This routine assumes we are printing only one page and that
 *  each line does not exceed the page width.  We may want to fix
 *  this in a future version.
 */
#pragma segment Print
print_getinfo(window)
WindowPtr	window;
{
	Str255		title;
	time_t		seconds;
	short		x;
	short		t;
	Rect		page_rect;
	char		*tp, *sp;
	NODE_INFO 	**select_node;
	Handle		tempH = NULL;
	Rect		iconRect;
	Str255		temp_string;
	short 		save_font,save_size;
	GrafPtr 	gp;
	
     /* Figure out page headers */
     p_date[0] = NULL;
     p_from[0] = NULL;
     p_subject[0] = NULL;
     page_num = 0;
		
	 GetWTitle(window, title );
	 p2cstr(title);
	 strncpy(p_subject, title, sizeof(p_subject));
	 p_subject[sizeof(p_subject)-1] = '\0';				/* make sure there is an ending null char */
	 	 
	 time(&seconds);
	 strncpy(p_date, ctime(&seconds), sizeof(p_date));
	 p_date[sizeof(p_date)-1] = '\0';
	 tp = strstr(p_date,"\n");
	 if ( tp != NULL )
	 	*tp = '\0';
		
	 PrOpenPage(pport, nil);
	 if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"PrOpenPage");
	 print_header();
	 
	 GetPort(&gp);
     save_font = gp->txFont;
     save_size = gp->txSize;
     if (((((**print_handle).prStl.wDev) >> 8) & 0xFF) == bDevCItoh)
	 	TextFont(geneva);
     else
	 	TextFont(helvetica);
     TextSize(10);

	 page_rect = (**print_handle).prInfo.rPage;
	 x = page_rect.left + 30;						/* left margin for drawing label */
	 t = page_rect.left + 150;						/* left margin for drawing text */

	 (long)select_node = GetWRefCon(window);
	  HLock((Handle)select_node);
	 
	 MoveTo(t, page_y);
	 DrawText((**select_node).title,0,strlen((**select_node).title));
			
	 switch(*((**select_node).type)) {
		case TEXT_ITEM:
			tempH = GetResource(ICN,DOCUMENT_ICON);	/* get document icon */
			break;
		case MENU_ITEM:
			tempH = GetResource(ICN,FOLDER_ICON);	/* get folder icon */
			break;
		case PHONE_ITEM:
			tempH = GetResource(ICN,PHONE_ICON);	/* get phone icon */
			break;
		case SERVER_ITEM:
			tempH = GetResource(ICN,PIPS_ICON);
			break;
		case IMAGE_ITEM:
			tempH = GetResource(ICN,IMAGE_ICON);
			break;
	}

	if ( tempH != NULL ) {
		iconRect.top = page_y - pline_height + 3;
		iconRect.bottom = page_y + 3;	/* add 3 pixels, it looks better */
		iconRect.left = 30;				/* offset two pixels from border */
		iconRect.right = 46;

		PlotIcon(&iconRect,tempH); 		/* draw icon */
	}
	
	/*  print_label takes two arguments, label name and label length */
	/*  print_info takes two arguments, text name, text length */
	page_y += pline_height;
	print_label("ID:", 3);
	print_info((**select_node).node_id, strlen((**select_node).node_id)); 
	
	print_label("Short Source:",13);
	print_info((**select_node).source, strlen((**select_node).source)); 
	
	print_label("Long Source:",12);
	print_info((**select_node).source_long, strlen((**select_node).source_long)); 
	
	print_label("Contact:",8);
	/* print each token on a seperate line */
	strcpy(temp_string,(**select_node).source_name);
	for(sp=temp_string,tp=temp_string; *sp != NULL; sp++) {
		if (*sp == '\n' || *sp == ',') {
			*sp = NULL;
			print_info(tp,strlen(tp));
			tp = sp + 1;
		}
	}
	/* print last token in list */
	print_info(tp,strlen(tp));
	
	print_label("Email:", 6);
	/* print each token on a seperate line */
	strcpy(temp_string,(**select_node).source_email);
	for(sp=temp_string,tp=temp_string; *sp != NULL; sp++) {
		if (*sp == '\n' || *sp == ',') {
			*sp = NULL;
			print_info(tp,strlen(tp));
			tp = sp + 1;
		}
	}
	/* print last token in list */
	print_info(tp,strlen(tp));
	
	print_label("Phone:",6);
	/* print each token on a seperate line */
	strcpy(temp_string,(**select_node).source_phone);
	for(sp=temp_string,tp=temp_string; *sp != NULL; sp++) {
		if (*sp == '\n' || *sp == ',') {
			*sp = NULL;
			print_info(tp,strlen(tp));
			tp = sp + 1;
		}
	}
	/* print last token in list */
	print_info(tp,strlen(tp));

	if ( *((**select_node).type) == TEXT_ITEM || *((**select_node).type) == IMAGE_ITEM) {
		print_label("Path:",5);
		print_info((**select_node).path, strlen((**select_node).path)); 
	}
	
	print_label("Keywords:",9);
	/* print each token on a seperate line */
	strcpy(temp_string,(**select_node).source_topic);
	for(sp=temp_string,tp=temp_string; *sp != NULL; sp++) {
		if (*sp == '\n' || *sp == ',') {
			*sp = NULL;
			print_info(tp,strlen(tp));
			tp = sp + 1;
		}
	}
	/* print last keyword in list */
	print_info(tp,strlen(tp));

	HUnlock((Handle)select_node);
	PrClosePage(pport);
	
	TextFont(save_font);
    TextSize(save_size);
    TextFace(normal);
}


#pragma segment Print
print_list(window)
WindowPtr	window;
{
	Str255	title;
	Str255	menu;
	time_t	seconds;
	short	x;
	Rect	page_rect;
	short	list_begin;
	short	list_bottom;
	Str255	list_buffer;
	char	*tp;
	int		rc;
	Handle	tempH = NULL;
	Rect	iconRect;
	char	type[2];
	short	ctr;
	Str255	temp;
	short	indent_level;
	Str255	ident_string;

     /* Figure out page headers */
     p_date[0] = '\0';
     p_from[0] = '\0';
     p_subject[0] = '\0';
     page_num = 0;
		
	 /* there is no subject - leave this null */
	 
	 GetWTitle(window, menu );
	 p2cstr(menu);
	 /* get rid of the # items, ie. "(n items)" from the menu title */
	 for (tp = &menu[strlen(menu) - 1]; *tp != '('; tp-- );
	 if (*tp == '(')
	 	*tp = '\0';
	 strncpy(p_from, menu, sizeof(p_from));
	 p_from[sizeof(p_from)-1] = '\0';
	 if (strlen(menu) >= sizeof(p_from)-1) {
	 	ctr = 3;
	 	for(tp=&p_from[sizeof(p_from)-2];ctr>0;ctr--,tp--)
			*tp = '.';
	 }
	 
	 time(&seconds);
	 strncpy(p_date, ctime(&seconds), sizeof(p_date));
	 p_date[sizeof(p_date)-1] = '\0';
	 tp = strstr(p_date,"\n");
	 if ( tp != NULL )
	 	*tp = '\0';
		
	 PrOpenPage(pport, nil);
	 if (PrError() != noErr)
	 	OpenAlertDialog(PRINT_ERROR,"PrOpenPage");
	 print_header();
	 
	 page_rect = (**print_handle).prInfo.rPage;
	 x = page_rect.left + 30;						/* left margin for drawing text */
		
	 list_bottom = list_end() - 1;		
	 list_begin = 0;
	 
	 for(;list_begin <= list_bottom; list_begin++) {
	 	if (need_page()) {
			if (num_lines != -1) {
				PrClosePage(pport);
			}
			PrOpenPage(pport,nil);
			print_header();
		}
		
		list_get_buffer(list_buffer,list_begin); 
		rc = get_field(list_buffer,TITLE,title);
		
		if (rc) {
			/* create the proper ident levels */
			rc = get_field(list_buffer,LEVEL,ident_string);
			indent_level = atoi(ident_string);
			*temp = '\0';
			for(ctr=1;ctr < indent_level;ctr++)
				strcat(temp,"  ");
				
			if ( *temp != '\0' ) {
				if (strlen(temp) + strlen(title) < sizeof(title)) {
					strcat(temp,title);
					strcpy(title,temp);
				}
			}
		}
	
		if (rc) {
			MoveTo(x, page_y);
			DrawText(title,0,strlen(title));
			
			rc = get_field(list_buffer,TYPE,type);
			if ( rc ) {
				switch(*type) {
					case TEXT_ITEM:
						tempH = GetResource(ICN,DOCUMENT_ICON);	/* get document icon */
						break;
					case MENU_ITEM:
						tempH = GetResource(ICN,FOLDER_ICON);	/* get folder icon */
						break;
					case PHONE_ITEM:
						tempH = GetResource(ICN,PHONE_ICON);	/* get phone icon */
						break;
					case SERVER_ITEM:
						tempH = GetResource(ICN,PIPS_ICON);
						break;
					case IMAGE_ITEM:
						tempH = GetResource(ICN,IMAGE_ICON);
						break;
				}
	
				if ( tempH != NULL ) {
					iconRect.top = page_y - pline_height + 3;
					iconRect.bottom = page_y + 3;	/* add 3 pixels, it looks better */
					iconRect.left = 5;				/* offset two pixels from border */
					iconRect.right = 21;
			
					PlotIcon(&iconRect,tempH); 		/* draw icon */
				}
			}
			
			page_y += pline_height;
			num_lines++;
		}
			
	 }
	 
	 PrClosePage(pport);
}

#pragma segment Print
need_page()
{
     return (num_lines < 0 || page_y > (**print_handle).prInfo.rPage.bottom - 10);
}

#pragma segment Print
print_header()
{
     char page_txt[10];
     short center,flen,dlen,save_font,page_left,save_size;
     GrafPtr gp;
	 Str255	appName;

     page_num++;

     GetPort(&gp);
     save_font = gp->txFont;
     save_size = gp->txSize;
     if (((((**print_handle).prStl.wDev) >> 8) & 0xFF) == bDevCItoh)
	  TextFont(geneva);
     else
	  TextFont(helvetica);
     TextSize(10);
     TextFace(bold);
     
     sprintf(page_txt, "Page %d", page_num);

     page_left = (**print_handle).prInfo.rPage.right - stringwidth(page_txt) - 3;
     center = ((**print_handle).prInfo.rPage.left + (**print_handle).prInfo.rPage.right) / 2;

     flen = stringwidth(p_from);
     dlen = stringwidth(p_date);

     page_y = 0;
     MoveTo(3, page_y);
     LineTo((**print_handle).prInfo.rPage.right - 3, page_y);
     
     page_y = 11;
     MoveTo(3, page_y);
     drawstring(p_from);
	 
	 pref_get_string(APPLICATION_NAME,appName);
	 c2pstr(appName);
     MoveTo(center - (StringWidth(appName) / 2), page_y);
     DrawString(appName);

     MoveTo((**print_handle).prInfo.rPage.right - 3 - dlen, page_y);
     drawstring(p_date);

     page_y += 16;     
     MoveTo(3, page_y);
     drawstring(p_subject);

     MoveTo(page_left, page_y);
     drawstring(page_txt);

     TextFont(save_font);
     TextSize(save_size);
     TextFace(normal);

     page_y += 5;
     MoveTo(3, page_y);
     LineTo((**print_handle).prInfo.rPage.right - 3, page_y);
     
     page_y += 15;
     num_lines = 0;
}

