#define NOLIB 1
/*-------------------------------------------------------------------------+
 |									   |
 | Name:    shopict.c							   |
 | Purpose: example program on how to use some of the features of	   |
 |	    iff.library 						   |
 |									   |
 | Author:  RWA 				   Date: 8/89		   |
 +-------------------------------------------------------------------------*/
#include <devices/printer.h>
#include <libraries/dosextens.h>
#include <intuition/intuition.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>
#include <workbench/icon.h>
#include <functions.h>
#include <stdio.h>
#ifndef NOLIB
#include "ctype.h"
#include "string.h"
#endif
#include "ifflib.h"

/* Aztec definitions of this have a bug (1<< instead of 1L<<)*/
#define SIGBREAKF_CTRLC        (1L<<SIGBREAKB_CTRL_C)
#define SIGBREAKF_CTRLD        (1L<<SIGBREAKB_CTRL_D)
#define SIGBREAKF_CTRLE        (1L<<SIGBREAKB_CTRL_E)
#define SIGBREAKF_CTRLF        (1L<<SIGBREAKB_CTRL_F)

/* Signals that indicate a break was sent from the user. */
#define SIGBREAK \
   (SIGBREAKF_CTRLC|SIGBREAKF_CTRLD|SIGBREAKF_CTRLE|SIGBREAKF_CTRLF)

void *IntuitionBase, *GfxBase, *IFFBase;

#ifdef NOLIB
extern void *IconBase;
#else
void *IconBase;
long _math = 0;
#endif

/* This is a mouse pointer image that looks like a 3.5 inch floppy disk,
 * it appears while the picture is being saved. */

#define DISKPTRHEIGHT 13L

unsigned short disk_pointer[30] =
{
0x0000, 0x0000,

0x1ff0, 0xe00c,
0x1f30, 0xe0ce,
0x1f30, 0xe0cf,
0x1f30, 0xe0cf,
0x1f30, 0xe0cf,
0x1ff0, 0xe00f,
0x0000, 0xffff,
0x0000, 0xffff,
0x0000, 0xffff,
0x0000, 0xffff,
0x0000, 0xffff,
0x0000, 0xbfff,
0x0000, 0xffff,

0x0000, 0x0000,
};

/* This is a mouse pointer image that represents a printer,
 * it is displayed while the picture is being printed. */

#define PRINTERPTRHEIGHT 13L

unsigned short printer_pointer[30] =
{
0x0000, 0x0000,

0x07fc, 0x0000,
0x04fc, 0x0000,
0x07fc, 0x0000,
0x0404, 0x0000,
0x07fc, 0x0000,
0x1c07, 0x0000,
0x27fd, 0x1802,
0x4003, 0x3ffc,
0xfffd, 0x0002,
0x8005, 0x7ffa,
0x8005, 0x7ffa,
0x8005, 0x7ffa,
0xfffe, 0x0000,

0x0000, 0x0000,
};


struct NewScreen ns =
{
0,0, 0,0, 0,  /* LE, TE, W, H, D */
0,0,	      /* pns */
0,	      /* ViewModes */
CUSTOMSCREEN | SCREENBEHIND | SCREENQUIET, /* type */
0L,	      /* font */
(UBYTE *)"View",       /* title */
0L,	      /* gadgets */
0L,	      /* bitmap */
};

struct NewWindow nw =
{
0,0,0,0,       /* LE,TE,W,H */
0,0,	       /* pns */
RAWKEY | MOUSEBUTTONS,	      /* IDCMP */
SIMPLE_REFRESH | BACKDROP | BORDERLESS | ACTIVATE | RMBTRAP, /* flags */
0L,	       /* Gadget */
0L,	       /* checkmark */
(UBYTE *)"",   /* title */
0L,	       /* screen */
0L,	       /* bitmap */
0,0,	       /* min */
0,0,	       /* max */
CUSTOMSCREEN,  /* type */
};

UWORD colors[4096];
UWORD ncolors;

void p(hdr)
register BitMapHeader *hdr;
{
printf("width: %d,  height: %d\n",(long)hdr->w,(long)hdr->h);
printf("x: %d, y: %d\n",(long)hdr->x,(long)hdr->y);
printf("nPlanes: %d\n",(long)hdr->nPlanes);
printf("masking: %d\n",(long)hdr->masking);
printf("compression: %d\n",(long)hdr->compression);
printf("transparentColor: %d\n",(long)hdr->transparentColor);
printf("xAspect: %d, yAspect:%d\n",
   (long)hdr->xAspect,(long)hdr->yAspect);
printf("pageWidth: %d, pageHeight: %d\n",
   (long)hdr->pageWidth,(long)hdr->pageHeight);

if( hdr->viewmodes != GETVIEWMODES )
   {
   printf("ViewModes: 0");
   if( hdr->viewmodes & PFBA ) printf("|PFBA");
   if( hdr->viewmodes & DUALPF ) printf("|DUALPF");
   if( hdr->viewmodes & HIRES ) printf("|HIRES");
   if( hdr->viewmodes & LACE ) printf("|LACE");
   if( hdr->viewmodes & HAM ) printf("|HAM");
   if( hdr->viewmodes & VP_HIDE ) printf("|VP_HIDE");
   if( hdr->viewmodes & GENLOCK_VIDEO ) printf("|GENLOCK_VIDEO");
   if( hdr->viewmodes & GENLOCK_AUDIO ) printf("|GENLOCK_AUDIO");
   if( hdr->viewmodes & EXTRA_HALFBRITE ) printf("|EXTRA_HALFBRITE");
   printf("\n");
   }
}

/* Gives help to CLI users */
void helpme()
{
static char *help[] =
{
      "            ShoPict IFF Viewer help\n",
"CLI SYNTAX:  ShoPict [-v] [-t<toolname>] <pictures> <pictures> ...",
"             -v prints stats on the file",
"             -t<toolname> makes icon tool = <toolname>",
"             The wild-card characters * and ? are accepted.\n",
"From WBench: Set the default tool to ShoPict in the info file.",
"             Multiple icons can be \"shift selected\"\n",
"While viewing:",
"             The 'I' key writes an icon for the picture.",
"             The 'P' key prints the picture.",
"             The 'S' key saves the picture with an icon to",
"             RAM:temp.pic",
0L,
};
register char **s;
for( s = help; *s; s++ )
   printf("%s\n",*s);
}

/* cleans out a message port */

void CleanPort(port)
register struct MsgPort *port;
{
struct IntuiMessage *msg;
while( msg = (struct IntuiMessage *)GetMsg(port) )
   ReplyMsg((struct Message *)msg);
}


short showpicture(fname,toolname,verbose)
register char *fname;
register char *toolname;
short verbose;
{
extern long open_prtdev(), DumpRPort();
extern short PutProject();
extern struct Image FaceOn_img, FaceOff_img;

BitMapHeader hdr;
register struct IntuiMessage *i;
register struct Window *w = 0L;
register struct Screen *s = 0L;
UWORD *clrs = colors, its_cool = 1, prt = 0, save = 0, icn = 0;
struct BitMap *bm;
register ULONG signals, waitsig, isig;
register short rv = 0;
struct NewWindow _nw;
struct NewScreen _ns;
static char *tooltypes[] = {"FILETYPE=ILBM",0L,};

if( fname )
   {
   hdr.viewmodes = GETVIEWMODES;
   if( !QueryIFF(fname,&hdr) )
      {
      if( verbose )
	 p(&hdr);
      _nw = nw;
      _ns = ns;

      _ns.Width = hdr.pageWidth;
      _ns.Height = hdr.pageHeight;
      _ns.Depth = hdr.nPlanes;

      /* Most IFF pictures don't contain ViewModes,
       * so the viewmodes variable will be un-changed.
       * also older versions of the IFF.LIBRARY don't
       * support the ViewModes variable.  */
      if( hdr.viewmodes == GETVIEWMODES )
	 {
	 if( hdr.pageWidth > 384 && hdr.nPlanes < 5 ) _ns.ViewModes |= HIRES;
	 if( hdr.pageHeight > 240 ) _ns.ViewModes |= LACE;
	 if( hdr.nPlanes > 5 ) _ns.ViewModes |= HAM;
	 }
      else _ns.ViewModes = hdr.viewmodes;

      /* open the screen */
      if( !(s = OpenScreen(&_ns)) )
	 {
	 rv = 20;
	 goto abort;
	 }

      /* this piece of code handles over-scanned pictures */
      if( _ns.ViewModes & HIRES )
	 {
	 if( _ns.Width > 640 ) s->ViewPort.DxOffset = -32;
	 }
      else if( _ns.Width > 320 ) s->ViewPort.DxOffset = -16;
      if( _ns.ViewModes & LACE )
	 {
	 if( _ns.Height > 400 ) s->ViewPort.DyOffset = -32;
	 }
      else if( _ns.Height > 200 ) s->ViewPort.DyOffset = -16;
      if( s->ViewPort.DxOffset || s->ViewPort.DyOffset ) RethinkDisplay();

      /* set up and open the new window */
      bm = &s->BitMap;
      _nw.MaxWidth = _nw.MinWidth = _nw.Width = hdr.w;
      _nw.MinHeight = _nw.MaxHeight = _nw.Height = hdr.h;
      _nw.Screen = s;
      if( !(w = OpenWindow(&_nw)) )
	 {
	 rv = 21;
	 goto abort;
	 }

      /* load the iff picture */
      if( rv = GetIFF_bitmap(fname,&bm,&clrs,&ncolors,0) )
	 goto abort;

      /* load the colors into the screen's view port */
      LoadRGB4(&s->ViewPort,clrs,(long)ncolors);

      /* bring the screen to the front */
      ScreenToFront(s);

      isig = (1L << w->UserPort->mp_SigBit);
      waitsig = isig | SIGBREAK;

      /* input loop */
      while(its_cool)
	 {
	 signals = Wait(waitsig);
	 if( signals & isig )
	    {
	    while( i = (struct IntuiMessage *)GetMsg(w->UserPort) )
	       {
	       if( i->Class == RAWKEY )
		  {
		  switch(i->Code)
		     {
		     case 0x40: its_cool = 0; rv = 0; break;
		     case 0x19: prt = 1; break;
		     case 0x21: save = 1; break;
		     case 0x17: icn = 1; break;
		     default: break;
		     }
		  }
	       ReplyMsg((struct Message *)i);
	       }

	    /* this part prints the picture if the user presses
	     * the 'P' key. */
	    if( prt && (!(signals & SIGBREAK)) )
	       {
	       SetPointer(w,(short *)printer_pointer,PRINTERPTRHEIGHT,16L,0L,0L);
	       if( !open_prtdev() )
		  {
		  DumpRPort(&s->RastPort,&s->ViewPort,(UWORD)0,(UWORD)0,
		  hdr.w,hdr.h,0L,0L,(UWORD)(SPECIAL_FULLCOLS|SPECIAL_FULLROWS));
		  close_prtdev();
		  }
	       ClearPointer(w);
	       prt = 0;
	       CleanPort(w->UserPort);
	       }

	    /* This saves the picture if the user presses the 'S' key. */
	    if( save && (!(signals & SIGBREAK)) )
	       {
	       SetPointer(w,(short *)disk_pointer,DISKPTRHEIGHT,16L,0L,0L);
	       if( rv = PutIFF_screen("ram:temp.pic",s) )
		  goto abort;
	       if( rv = PutProject("ram:temp.pic",toolname,
			&FaceOff_img,&FaceOn_img,tooltypes,0L) )
		  goto abort;
	       ClearPointer(w);
	       save = 0;
	       CleanPort(w->UserPort);
	       }

	    /* This writes an icon for the picture if 'I' is pressed. */
	    if( icn && (!(signals & SIGBREAK)) )
	       {
	       SetPointer(w,(short *)disk_pointer,DISKPTRHEIGHT,16L,0L,0L);
	       if( rv = PutProject(fname,toolname,
			&FaceOff_img,&FaceOn_img,tooltypes,0L) )
		  goto abort;
	       ClearPointer(w);
	       icn = 0;
	       CleanPort(w->UserPort);
	       }
	    }

	 if( signals & SIGBREAK )
	    {
	    rv = 10;
	    its_cool = 0;
	    }
	 }

      CleanPort(w->UserPort);
      abort:
      if( rv )
	 printf("Program Aborted code: %u\n",rv);
      if( w ) CloseWindow(w);
      if( s ) CloseScreen(s);
      }
   }

return(rv);
}

main(argc,argv)
#ifndef NOLIB
long argc;	/* called by _main with 32 bit ints */
#else
short argc;
#endif
char *argv[];
{
extern void *OpenLibrary(), CloseLibrary();

extern short QueryIFF();
extern struct WBStartup *WBenchMsg;
char *ptr, *scdir(), *toolname = "c:shopict";
register struct WBArg *wa;
register short i, verbose;
register int rv;

if( argc > 1 || argc == 0 )
   {
   if( !(GfxBase = OpenLibrary("graphics.library",0L)) )
      goto abort;
   if( !(IntuitionBase = OpenLibrary("intuition.library",0L)) )
      goto abort;
   if( !(IFFBase = OpenLibrary(IFFNAME,IFFVERSION)) )
      goto abort;
   if( !(IconBase = OpenLibrary(ICONNAME,0L)) )
      goto abort;

    if( argc ) /* From CLI */
      {
      for( i = 1, verbose = 0; i < argc; i++)
	 {
	 if( argv[i][0] == '-' )
	    {
	    if( toupper(argv[i][1]) == 'V' )
		  {
		  verbose = 1;
		  continue;
		  }
	    else if( toupper(argv[i][1]) ==  'T' )
		  {
		  toolname = &argv[i][2];
		  continue;
		  }
	    }

	 if( strpbrk(argv[i],"*?") )
	    {
	    while( ptr = scdir(argv[i]) )
	       if( rv = showpicture(ptr,toolname,verbose) )
		  goto abort;
	    }
	 else if( rv = showpicture(argv[i],toolname,verbose) )
	    goto abort;
	 }
      }
    else  /* From Workbench */
      {
      wa = WBenchMsg->sm_ArgList;
      for( wa++, i = 1, verbose = 0; i < WBenchMsg->sm_NumArgs; i++, wa++)
	 {
	 if( wa->wa_Lock )
	    {
	    CurrentDir((struct FileLock *)wa->wa_Lock);
	    if( rv = showpicture(wa->wa_Name,toolname,verbose) )
	       break;
	    }
	 }
      }
   rv = 0;

   abort:
   if( IconBase ) CloseLibrary(IconBase);
   if( IFFBase ) CloseLibrary(IFFBase);
   if( IntuitionBase ) CloseLibrary(IntuitionBase);
   if( GfxBase ) CloseLibrary(GfxBase);
   }
else
   helpme();
_exit(rv);
}
