/****************************/
/*        FILE              */
/* (c)2002 Pangea Software  */
/* By Brian Greenstone      */
/****************************/


/***************/
/* EXTERNALS   */
/***************/


extern	WindowPtr	gPictureWindow;
extern	GWorldPtr	gPictureWorld;
extern	CTabHandle	gPictColorTable;
extern	WindowPtr	gSpritesWindow;
extern	GWorldPtr	gSpritesWorld;
extern	PictInfo	gThePictInfo;
extern	PaletteHandle  gPictPalette;
extern	short		displayedFrame;
extern	short		gPageNum;
extern	short	gMyRezFile;
extern	Byte		gCurrentPixelDepth;

/****************************/
/*    PROTOTYPES            */
/****************************/

pascal void myEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms,
						NavCallBackUserData callBackUD);

pascal Boolean myFilterProc(AEDesc*theItem,void*info, NavCallBackUserData callBackUD, NavFilterModes filterMode);


/****************************/
/*    CONSTANTS             */
/****************************/

#define	CR_HEIGHT	12

/**********************/
/*     VARIABLES      */
/**********************/

static Str255			gDefaultFileName;

static u_long			gNavFilterFileType = 0;

static FSSpec			gNavRecentSpec = {0,0,0};


/***************** SKIP TO NUMBER ***************/
//
// Scans memory starting at textPtr for a signed ASCII number
//
// INPUT: textPtr = ptr to memory to start search
//
// OUTPUT:  ptr to start of #
//

char *SkipToNumber(char *textPtr)
{
	while(((*textPtr < '0') || (*textPtr > '9')) && ((*textPtr != '-')))
		textPtr++;

	return(textPtr);
}

/***************** SKIP TO CHAR ***************/
//
// Scans memory starting at textPtr for specified character or CR
//
// INPUT: textPtr = ptr to memory to start search
//			c = char to search for
//
// OUTPUT:  TRUE if found, FALSE if not found
//			textPtr = updated ptr
//

Boolean SkipToChar(char **textPtr, char c)
{
char	*t;
	
	t = *textPtr;

	while(*t != c)
	{
		if (*t == CHAR_RETURN)				// if CR, then assume not there and return error
			return(FALSE);
		t++;
	}

	*textPtr = t;							// pass back new ptr
	return(TRUE);
}



/***************** READ NUMBER STRING ***************/
//
// Reads a signed ASCII number @ textPtr
//
// INPUT: textPtr = ptr to memory to start
//		  destStr = ptr to Str255 where string will go
//
// OUTPUT:  ptr to char past end of #
//

char *ReadNumberString(char *textPtr, Str255 destStr)
{
short	i;

	textPtr = SkipToNumber(textPtr);

	i = 1;
	while(((*textPtr >= '0') && (*textPtr <= '9')) || (*textPtr == '-'))
		destStr[i++] = *textPtr++;
	destStr[0] = i-1;

	return(textPtr);
}

/**************** READ FLOATING POINT NUMBER FROM STRING *******************/
//
// Assumes that input ptr points to first char in # string.
//
// INPUT:	textHandle = ptr to (char *) so that updated value can be returned
//

float	ReadFloatingPointNumFromString(char **textHandle)
{
Str255	numStr;
long	hi,u,i;
char	*textPtr;
float	uF;
Boolean	isNeg;

	textPtr = *textHandle;

	isNeg = (*textPtr == '-');					// see if (-) #

	textPtr = ReadNumberString(textPtr,numStr);	// read the # string for integer part of #
	StringToNum(numStr,&hi);
	uF = 0;
	if (*textPtr == '.')						// see if read in decimals
	{
		textPtr = ReadNumberString(textPtr,numStr);	// read the decimals
		StringToNum(numStr,&u);
		
		uF = u;									// convert to FLOAT
		for (i=0;i<numStr[0];i++)
			uF = uF/10;
	}
	
	if (isNeg)
		uF = hi-uF;								// add in the integer part of fraction
	else
		uF = hi+uF;

	*textHandle = textPtr;						// update source ptr
	return(uF);									// return value
}

#pragma mark -


/************************ NAV SERVICES:  EVENT PROC *****************************/

pascal void myEventProc(NavEventCallbackMessage callBackSelector, NavCBRecPtr callBackParms,
						NavCallBackUserData callBackUD)
{
#pragma unused (callBackUD)
	
	switch (callBackSelector)
	{
		case	kNavCBEvent:
				switch (((callBackParms->eventData).eventDataParms).event->what)
				{
					case 	updateEvt:
//							MyHandleUpdateEvent(window, (EventRecord*)callBackParms->eventData.event);
							break;
				}
				break;
	}
}


/************************ NAV SERCIES: MY FILTER PROC **************************/

pascal Boolean myFilterProc(AEDesc*theItem,void*info, NavCallBackUserData callBackUD, NavFilterModes filterMode)
{
#pragma unused (callBackUD, filterMode)

Boolean display 			= true;
NavFileOrFolderInfo	*theInfo = (NavFileOrFolderInfo*)info;


	if (gNavFilterFileType == 0)						// see if no filter
		return(true);


	if (theItem->descriptorType == typeFSS)
		if (!theInfo->isFolder)
			if (theInfo->fileAndFolder.fileInfo.finderInfo.fdType != gNavFilterFileType)			// only show us the saved games
				display = false;
				
	return display;
}



/******************** NAV SERVICES: GET DOCUMENT ***********************/

OSErr GetFileWithNavServices(FSSpecPtr defaultLocationfssPtr, FSSpec *documentFSSpec, u_long fileType)
{
NavDialogOptions 	dialogOptions;
AEDesc 				defaultLocation;
NavEventUPP 		eventProc 	= nil;	//NewNavEventUPP(myEventProc);
NavObjectFilterUPP filterProc 	= NewNavObjectFilterUPP(myFilterProc);
OSErr 				anErr 		= noErr;

	if (defaultLocationfssPtr == nil)
		defaultLocationfssPtr = &gNavRecentSpec;

	gNavFilterFileType = fileType;

			/* Specify default options for dialog box */
	
	anErr = NavGetDefaultDialogOptions(&dialogOptions);
	if (anErr == noErr)
	{
			/* Adjust the options to fit our needs */
						
		dialogOptions.dialogOptionFlags |= kNavSelectDefaultLocation;	// Set default location option				
		dialogOptions.dialogOptionFlags ^= kNavAllowPreviews;			// Clear preview option
		dialogOptions.dialogOptionFlags ^= kNavAllowMultipleFiles;		// Clear multiple files option


				/* make descriptor for default location */

		anErr = AECreateDesc(typeFSS,defaultLocationfssPtr, sizeof(*defaultLocationfssPtr), &defaultLocation);
//		if (anErr ==noErr)
		{
			/* Get 'open'resource.  A nil handle being returned is OK, this simply means no automatic file filtering. */
				
//			static NavTypeList			typeList = {'????', 0, 1, '3DMF'};	// set types to filter			
//			NavTypeListPtr 	typeListPtr = &typeList;	// = (NavTypeListHandle)GetResource('open',128);
			NavTypeListHandle typeListHand = nil; // &typeListPtr;
			NavReplyRecord 		reply;


			/* Call NavGetFile() with specified options and declare our app-defined functions and type list */

			anErr = NavGetFile(&defaultLocation, &reply, &dialogOptions, eventProc, nil, filterProc, typeListHand,nil);
			if ((anErr == noErr) && (reply.validRecord))
			{
					/* Deal with multiple file selection */
					
				long 	count;
				
				anErr = AECountItems(&(reply.selection),&count);
				
				
					/* Set up index for file list */
					
				if (anErr == noErr)
				{
					long i;
					
					for (i = 1; i <= count; i++)
					{
						AEKeyword 	theKeyword;
						DescType 	actualType;
						Size 		actualSize;
						
						/* Get a pointer to selected file */
					
						anErr = AEGetNthPtr(&(reply.selection), i, typeFSS,&theKeyword, &actualType,
											documentFSSpec, sizeof(FSSpec), &actualSize);
					}
				}
				
					
				/* Dispose of NavReplyRecord,resources,descriptors */
				
				anErr = NavDisposeReply(&reply);
			}
					
			(void)AEDisposeDesc(&defaultLocation);
		}
	}
	
	
		/* CLEAN UP */
		
	if (eventProc)
	{
		DisposeNavEventUPP(eventProc);
		eventProc = nil;
	}
	if (filterProc)
	{
		DisposeNavObjectFilterUPP(filterProc);
		filterProc = nil;
	}
	
	if (!anErr)
		gNavRecentSpec = *documentFSSpec;					// remember where it was
	
	return anErr;
}


/********************** PUT FILE WITH NAV SERVICES *************************/

OSErr PutFileWithNavServices(NavReplyRecord *reply, FSSpec *outSpec)
{
OSErr 				anErr 			= noErr;
NavDialogOptions 	dialogOptions;
OSType 				fileTypeToSave 	='TUNL';
OSType 				creatorType 	='TunL';
NavEventUPP 		eventProc = nil; //NewNavEventUPP(myEventProc);

	anErr = NavGetDefaultDialogOptions(&dialogOptions);
	if (anErr == noErr)
	{
		CopyPStr(gDefaultFileName, dialogOptions.savedFileName);					// set default name
		
		anErr = NavPutFile(nil, reply, &dialogOptions, nil, fileTypeToSave, creatorType, nil);
		if ((anErr == noErr) && (reply->validRecord))
		{
			AEKeyword	theKeyword;
			DescType 	actualType;
			Size 		actualSize;
			
			anErr = AEGetNthPtr(&(reply->selection),1,typeFSS, &theKeyword,&actualType, outSpec, sizeof(FSSpec), &actualSize);
		}
	}

	if (eventProc)
	{
		DisposeNavEventUPP(eventProc);
		eventProc = nil;
	}

	if (!anErr)
		gNavRecentSpec = *outSpec;					// remember where it was

	return anErr;
}


