/*
 * $Source: $
 * $Revision: $
 * $Date: $
 * $State: $
 * $Author: $
 *
 *
 * $Log: $
 * Revision 3.1  3/10/92 wade
 * added IMAGE_KEY, IMAGE_ICON and IMAGE_TYPE
 * added ansi C atoi routine
 *
 */

/*  
 *	Copyright (c) 1991 by the Massachusetts Institute of Technology,
 *	For copying and distribution information, see the file
 *	"mit-copyright.h".
 *
 *  ldef.c  - WADE 10/11/89
 *		This routine creates the list definition procedure for drawing a list.
 *		It corresponds to the ldef.make to create the LDEF resource.
 */

#include 	<StdLib.h>
#include	<stdio.h>
#include	<types.h>
#include	<quickdraw.h>
#include	<windows.h>
#include	<SysEqu.h>
#include	<menus.h>
#include	<fonts.h>
#include	<lists.h>
#include	<resources.h>
#include	<ToolUtils.h>
#include	<strings.h>
#include	<string.h>
#include	<fcntl.h>
#include	"pips.h"
#include 	"mit-copyright.h"

#define theHiliteMask	0x7FFFFFFF	/* bit 31 */
#define ICON			1229147982	/* resource type id */
#define ICN				1229147683
#define ICON_LENGTH		((2 * CharWidth(' ')) + 4) /* 2 pixels on either side of the icon */

Boolean	get_field( char *buffer, int field, char *value );
void	draw_icon(char *type, Boolean select, Rect *lRect);

pascal mldef(short  msg,
		 Boolean 	select,
		 Rect 		*lRect,
		 Cell 		the_cell,
		 short 		data_offset,
		 short 		data_len,
		 ListHandle lhandle)
{
	 char		buf[256];
	 short		buf_size = 256;
	 FontInfo	fInfo;
	 Str255		title;
	 char		type[2];
	 Boolean	rc;
	 Rect		tempRect;
	 Rect		tempRect2;
	 int		i_level;
	 short		ctr;
	 Str255		flag;
	
	#pragma unused ( data_offset)
	#pragma unused ( data_len )
	
     switch(msg) {
     	case lInitMsg:	
			GetFontInfo(&fInfo);						/* set proper indent distance */
			(*lhandle)->indent.h = fInfo.widMax / 3;
			(*lhandle)->indent.v = fInfo.ascent;
			break;
			
     	case lCloseMsg:
			break;
			
     	case lHiliteMsg:
			*(long *)HiliteMode &= theHiliteMask;		/* hilighting for color */
			tempRect.top = lRect->top;
			tempRect.bottom = lRect->bottom;
			tempRect.left = lRect->left + 2;			/* offset two pixels from border */
			tempRect.right = lRect->right;
			
			tempRect2.top = lRect->top;
			tempRect2.bottom = lRect->bottom;
			tempRect2.left = lRect->left + 2;			/* offset two pixels from border */
			tempRect2.right = lRect->right;

			/* get data from cell */
			LGetCell( buf, &buf_size, the_cell, lhandle );
			buf[buf_size] = '\0';						/* turn data into a C string */
			
			/* find start of text of do the invert function */
			i_level = buf[0] - 48;						/* convert character to int */
			for(ctr=1;ctr < i_level;ctr++) {
				tempRect.left = tempRect.left + (2 * CharWidth(' '));
			}
				
			/* add room for the icon */
			tempRect.left = tempRect.left + ICON_LENGTH;
				
			/* get list type - subject or document */
			rc = get_field(buf,TYPE,type);
			
			if (rc)	rc = get_field(buf,FLAGS,flag);
			if (rc)	{
				if (my_atoi(flag) & FRAME) {		
					draw_icon(type,select,&tempRect);	
					FrameRect(&tempRect2);					/* frame rect if reorder is on */
				}
				else
					if (my_atoi(flag) & SEL_HIGH) {
						tempRect2.bottom = tempRect2.top + 3;
						InvertRect(&tempRect2);				/* select the top half rectangle */
						draw_icon(type,select,&tempRect);
					}
					else
						if (my_atoi(flag) & SEL_LOW) {
							tempRect2.top = tempRect2.bottom - 3;	
							InvertRect(&tempRect2);				/* select the bottom half rectangle */
							draw_icon(type,select,&tempRect);
						}
						else {
							InvertRect(&tempRect);				/* select the full rectangle */
							draw_icon(type,select,&tempRect);

						}
			}
			
			break;
			
    	 case lDrawMsg:
													/* get data from cell */
			LGetCell( buf, &buf_size, the_cell, lhandle ); 
			buf[buf_size] = '\0'; 
			
			EraseRect(lRect);						/* remove existing data in rect */
			
			tempRect.top = lRect->top;
			tempRect.bottom = lRect->bottom; 
			tempRect.left = lRect->left + 2;		/* offset two pixels from border */
			tempRect.right = lRect->right;
			
			tempRect2.top = lRect->top;
			tempRect2.bottom = lRect->bottom; 
			tempRect2.left = lRect->left + 2;		/* offset two pixels from border */
			tempRect2.right = lRect->right;

			rc = get_field(buf,TITLE,title);		/* get display information */
			
			if (rc) {
				i_level = buf[0] - 48;				/* convert character to int */

				for(ctr=1;ctr < i_level;ctr++) {
					tempRect.left = tempRect.left + (2 * CharWidth(' '));
				}
				
				/* add room for the icon */
				tempRect.left = tempRect.left + ICON_LENGTH;
				
				/* draw with appropriate indentation level */
				MoveTo(tempRect.left, lRect->top + (*lhandle)->indent.v );

				c2pstr( title );					/* convert to a pascal string */
				DrawString( title );				/* draw text */

			}
			
			/* get list type - subject or document */
			rc = get_field(buf,TYPE,type);
			
			if (rc)	rc = get_field(buf,FLAGS,flag);
			if (rc)
				if (my_atoi(flag) & FRAME) {		
					draw_icon(type,select,&tempRect);	
					FrameRect(&tempRect2);					/* frame rect if reorder is on */
				}
				else {
					
					*(long *)HiliteMode &= theHiliteMask;	/* hilighting for color */
					
					/* is the list window in the background? */
					/* this will not work for multiple list window's , need to check which lhandle */
					if ((((WindowPeek)FrontWindow()) -> windowKind) != list) {
						/* menu window is in the background, frame the selected cell */
						if (LGetSelect(false, &the_cell, lhandle)) {
							draw_icon(type,select,&tempRect);
							FrameRect(&tempRect2);	
						}
						else
							draw_icon(type,select,&tempRect);
					}
					else {
						if ( select ) {
							/* if we a doing a reorder - just draw a line */
							if (my_atoi(flag) & SEL_HIGH) {
								tempRect2.bottom = tempRect2.top + 3;
								InvertRect(&tempRect2);				/* select the full rectangle */
							}
							else
								if (my_atoi(flag) & SEL_LOW) {
									tempRect2.top = tempRect2.bottom - 3;
									InvertRect(&tempRect2);			/* select the full rectangle */
								}
								else
									InvertRect(&tempRect);			/* select the partial rectangle */
						}
					
						draw_icon(type,select,&tempRect);
					}
				}
				
			break;
     }
}

/*
 *	get_field
 *
 */
Boolean
get_field(buf,field,value) 
char	*buf;
int		field;
char	*value;
{
	char	*curr_ptr;
	int		ctr;
	char	*last_ptr;
	int		rc;
	Str255	locker;
	Str255	path;
	Str255	flags;
	
	/* special case (like a symbalic field) to return the list type */
	if ( field == 0 ) {
		rc = get_field(buf,LOCKER,locker);
		rc = get_field(buf,PATH,path);
		rc = get_field(buf,FLAGS,flags);
			
		/* this is really bad, but here it is .... */
		if (strlen(path) == 0)
			value[0] = MENU_ITEM; /* subject record */
		else
			if (!strcmp(path,PHONE_KEY))
				value[0] = PHONE_ITEM; /* this is a phone type record */
			else 
				if (!strcmp(path,SERVER_KEY))
					value[0] = SERVER_ITEM;	/* worldwide techinfo servers */
				else
					if (my_atoi(flags) & IMAGE_KEY)
						value[0] = IMAGE_ITEM;	/* image flag */
					else
						/* must be a text item */
						value[0] = TEXT_ITEM;

		return rc;
	}
	
	curr_ptr = buf;
	last_ptr = buf;
	
	for (ctr = 1; ctr <= field; ctr++) {
		curr_ptr = strstr(curr_ptr,":");
		if ( curr_ptr == NULL )
			return false;
		else
			if (ctr != field) {
				curr_ptr = curr_ptr + 1;
				last_ptr = curr_ptr;
			}
	}
	
	strncpy(value,last_ptr,curr_ptr - last_ptr );
	value[curr_ptr - last_ptr] = '\0';
	
	return true;
}

/*
 *	draw_icon
 *
 */
void
draw_icon(type,select,lRect)
char	*type;
Boolean	 select;
Rect	*lRect;
{
	Handle	tempH = NULL;
	Rect	iconRect;
	short	resource;
			
	switch(*type) {
		case TEXT_ITEM:
			resource = DOCUMENT_ICON;
			ForeColor(blueColor);  	
			break;
		case MENU_ITEM:
			resource = FOLDER_ICON;
			ForeColor(greenColor);  	
			break;
		case PHONE_ITEM:
			resource = PHONE_ICON;
			ForeColor(cyanColor);  	
			break;
		case SERVER_ITEM:
			resource = PIPS_ICON;
			ForeColor(redColor);  	
			break;
		case IMAGE_ITEM:
			resource = IMAGE_ICON;
			ForeColor(redColor);  	
			break;
	}
	

	if (select)
		resource = resource + FILLED_ICON;
		
	tempH = GetResource(ICN,resource);
				
	if ( tempH != NULL ) {
		iconRect.top = lRect->top;
		iconRect.bottom = lRect->bottom;
		iconRect.left = lRect->left - ICON_LENGTH + 2;	/* offset two pixels from border */
		iconRect.right = lRect->left - 2;
			
		PlotIcon(&iconRect,tempH); 
	}
	
	/* reset background color */
	ForeColor(blackColor); 
}

my_atoi(p)
register char *p;
{
        register int n;
        register int f;

        n = 0;
        f = 0;
        for(;;p++) {
                switch(*p) {
                case ' ':
                case '\t':
                        continue;
                case '-':
                        f++;
                case '+':
                        p++;
                }
                break;
        }
        while(*p >= '0' && *p <= '9')
                n = n*10 + *p++ - '0';
        return(f? -n: n);
}
