/*****************************************************************************/
/* Controller.m								     */
/* implementation file of Controller class of ViewGif2 application           */
/* January 1990  Carl F. Sutter						     */
/* The Controller handes the whole program, and dispatches processing to     */
/* the various modules.  Most of the work is done by those isolated modules, */
/* so this "main program" is really quite simple.			     */
/*****************************************************************************/

#import "Controller.h"
#import "ViewBitmap.h"
#import <appkit/Application.h>
#import <appkit/OpenPanel.h>
#import <appkit/SavePanel.h>
#import <appkit/PageLayout.h>
#import <string.h>		 // for strcpy, strcat
#import <appkit/publicWraps.h>   // for NXBeep

@implementation Controller

/*****************************************************************************/
/* new - initialize the controller					     */
/*****************************************************************************/
+ new
   {
   self = [super new];
   /* set up the queue */
   Queue = [FileQueue new:self action:@selector(nextFromQueue:)];
   [Queue retrieveNextWhenReady];
   /* set up the decoder */
   Decoder = [DecodeGIF new:self action:@selector(decoderDone:)];
   /* set up the activate menu & slideshow panel */
   activateMenu = [ActivateMenu new];
   return( self );
   } /* new 1/31/90 CFS */
   

/*****************************************************************************/
/* showQueue: - tell queue to display its panel				     */
/*****************************************************************************/
- showQueue:sender
   {
   [Queue show:self];
   return( self );
   } /* showQueue: 1/22/90 CFS */


/*****************************************************************************/
/* showDecoder: - tell decoder to show its panel		             */
/*****************************************************************************/
- showDecoder:sender
   {
   [Decoder show:self];
   return( self );
   } /* showDecoder: 1/22/90 CFS */


/*****************************************************************************/
/* showSlideshow: - tell activate menu slide show panel to appear	     */
/*****************************************************************************/
- showSlideshow:sender
   {
   [activateMenu show:self];
   return( self );
   } /* showSlideshow: 3/7/90 CFS */


/***************************************************************************/
/* appAcceptsAnotherFile is an application delegate method which 	   */
/* returns whether it is OK for the application to try to open more files  */
/* with the appOpenFile:type:						   */
/***************************************************************************/
- (BOOL)appAcceptsAnotherFile:sender;
   {
   return( YES );
   } /* appAcceptsAnotherFile 1/22/90 CFS */


/***************************************************************************/
/* appOpenFile:type: - delegate message sent to open the specified file.   */
/* It is normally called by the Application object in response to open 	   */
/* requests from the Workspace.						   */
/***************************************************************************/
- (int)appOpenFile:(const char *)filename type:(const char *)aType;
   {
   return( [Queue addItem:filename] );  
   } /* appOpenFile 1/22/90 CFS */


/***************************************************************************/
/* openRequest - allows user to choose a new file(s) using the open panel  */
/***************************************************************************/
- openRequest:sender
   {
   const char		*directory;
   const char		*const *files;
   static const char	*const types[2] = {"gif", NULL};
   id openpanel =	[[OpenPanel new] allowMultipleFiles:YES];
   char 		szFileName[160];

   if ([openpanel runModalForTypes:types])
      {
      files = [openpanel filenames];		// list of multiple files
      directory = [openpanel directory];
      while (files && *files)
         {
	 strcpy( szFileName, directory );
	 strcat( szFileName, "/" );
	 strcat( szFileName, *files );
         [Queue addItem:szFileName];
	 files++;
	 }
      }	 
   return( self );
   } /* openRequest 1/22/90 CFS */


/***************************************************************************/
/* saveToTiff: - gets a filename to save the image in TIFF format	   */
/***************************************************************************/
- saveToTiff:sender;
   {
   char			szFileName[40];
   const char		*fileName;
   id savepanel =	[[SavePanel new] setPrompt:"Save To TIFF File:"];

   /* first, make sure a window is available to save */
   if ([NXApp mainWindow] == nil)
      {
      [self errorAlert:"No main window to save TIFF file for."];
      return( self );
      }
   
   /* get the gif filename, remove the .gif, and add a .tiff */
   strcpy( szFileName, [[NXApp mainWindow] title] );
   *(strrchr( szFileName, '.' )) = 0;
   strcat( szFileName, ".tiff" );
   
   /* run the save panel, and if a name was entered, save the bitmap */
   if (([savepanel runModalForDirectory:"." file:szFileName]) && 
      (fileName = [savepanel filename]))
         [[[[NXApp mainWindow] contentView] docView] saveBitmapToTiff:fileName];
	 
   return( self );
   } /* saveToReqest 10/27/89 CFS */


/***************************************************************************/
/* nextFromQueue - message from queue with a new file to decode	 	   */
/***************************************************************************/
- nextFromQueue:(char *)szFileName
   {
   /* send the file to the decoder */
   [Decoder decodeFile:szFileName];
   strcpy( szCurrentFile, strrchr( szFileName, '/' ) + 1);
   return( self );
   } /* nextFromQueue 1/22/90 CFS */


/***************************************************************************/
/* decoderDone - message from decoder saying it is ready for a new file    */
/***************************************************************************/
- decoderDone:(Bitmap *)bmpImage
   {
   ViewBitmap	*displayView;
   
   if (bmpImage != nil)
      {
      displayView = [ViewBitmap newBitmap:bmpImage title:szCurrentFile
                                topLeft:[self nextTopLeft]];
      [displayView setMiniwindowIcon:"gif"];   
      [activateMenu addDocument:[displayView window]];   
      [displayView setCloseNotify:activateMenu];
      }
   /* tell the queue to send a new file to decode */
   [Queue retrieveNextWhenReady];
   return( self );
   } /* decoderDone 1/23/90 CFS */


/***************************************************************************/
/* nextTopLeft - return the next good top left window position		   */
/***************************************************************************/
- (NXPoint)nextTopLeft
   {
   #define OFFSET 10.0
   #define MAX_STEPS 20
   #define INITIAL_X 356.0
   #define INITIAL_Y 241.0
   NXPoint	nxpTopLeft;
   static int	nCurStep = 0;
   
   nxpTopLeft.x = INITIAL_X + nCurStep * OFFSET;
   nxpTopLeft.y = INITIAL_Y + nCurStep * OFFSET;
   if (++nCurStep > MAX_STEPS) nCurStep = 0;
   return( nxpTopLeft );
   } /* nextTopLeft 1/24/90 CFS */


/***************************************************************************/
/* errorAlert - put the message in an alert panel			   */
/***************************************************************************/
- errorAlert:(char *)szMessage
   {
   NXRunAlertPanel( "ViewGif2 Error", szMessage, "OK", NULL, NULL );
   return( self );
   } /* errorAlert 10/30/89 CFS */


/***************************************************************************/
/* printRequest - print the main window					   */
/***************************************************************************/
- printRequest:sender
   {
   id  curView = [[[NXApp mainWindow] contentView] docView];
   if (curView == nil)
      {
      [self errorAlert:"No main window to print."];
      return( self );
      }
   [curView printPSCode:self];
   return( self );
   } /* printRequest 10/23/89 CFS */

   
/***************************************************************************/
/* pageLayout - bring up page layout panel				   */
/***************************************************************************/
- pageLayout:sender
   {
   [[PageLayout new] runModal]; 
   return( self );
   }  /* pageLayout 10/30/89 CFS */ 
 

@end
