;/*
lc -L -cfist -y -v -j73 showpict
quit
 * showpict.c
 */

/* showpict.c
 * Extremely simplistic generic picture displayer.
 *
 * This will display ANY picture type, as long as you have a
 * DataType that can handle it.
 *
 */

#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <graphics/gfx.h>
#include <intuition/intuition.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

#include <clib/alib_protos.h>
#include <clib/datatypes_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>

#include <pragmas/datatypes_pragmas.h>
#include <pragmas/dos_pragmas.h>
#include <pragmas/exec_pragmas.h>
#include <pragmas/graphics_pragmas.h>
#include <pragmas/intuition_pragmas.h>

/*****************************************************************************/

#define	DB(x)	;

/*****************************************************************************/

extern struct Library *SysBase, *DOSBase;

/*****************************************************************************/

struct Library *IntuitionBase;
struct Library *GfxBase;
struct Library *DataTypesBase;

/*****************************************************************************/

void ShowError (ULONG id)
{
    UBYTE msg[80];

    if (id)
    {
	if (id < 2000)
	    Fault (id, "", msg, 80);
	else
	    strcpy (msg, (char *) GetDTString (id));
	printf ("Error %ld : %s\n", id, msg);
    }
}

/*****************************************************************************/

void main (int argc, char **argv)
{
    ULONG *cregs = NULL, numcolors, i, r, g, b;
    struct dtFrameBox dtf = {NULL};
    struct FrameInfo fri = {NULL};
    struct BitMapHeader *bmhd;
    ULONG modeid = INVALID_ID;
    struct gpLayout gpl;
    struct Screen *scr;
    struct BitMap *bm;
    Object *o;

    /* Make sure we have an argument */
    if (argc >= 2)
    {
	/* Open all the libraries that we need */
	if (IntuitionBase = OpenLibrary ("intuition.library", 39))
	{
	    GfxBase = OpenLibrary ("graphics.library", 39);
	    if (DataTypesBase = OpenLibrary ("datatypes.library", 39))
	    {
		printf ("display \"%s\" as a picture.\n", argv[1]);

		/* Obtain a pointer to the picture object */
		if (o = NewDTObject ((APTR) argv[1],
				     DTA_SourceType, DTST_FILE,
				     DTA_GroupID, GID_PICTURE,
				     PDTA_Remap, FALSE,
				     TAG_DONE))
		{
		    /* Ask the object what kind of environment it needs */
		    dtf.MethodID = DTM_FRAMEBOX;
		    dtf.dtf_FrameInfo = &fri;
		    dtf.dtf_ContentsInfo = &fri;
		    dtf.dtf_SizeFrameInfo = sizeof (struct FrameInfo);
		    if (DoMethodA (o, &dtf) && fri.fri_Dimensions.Depth)
		    {
			DB (printf ("PropertyFlags : 0x%lx\n", fri.fri_PropertyFlags));
			DB (printf ("RedBits       : 0x%lx\n", fri.fri_RedBits));
			DB (printf ("GreenBits     : 0x%lx\n", fri.fri_GreenBits));
			DB (printf ("BlueBits      : 0x%lx\n", fri.fri_BlueBits));
			DB (printf ("Width         : %ld\n", (ULONG) fri.fri_Dimensions.Width));
			DB (printf ("Height        : %ld\n", (ULONG) fri.fri_Dimensions.Height));
			DB (printf ("Depth         : %ld\n", (ULONG) fri.fri_Dimensions.Depth));
			DB (printf ("Screen        : 0x%lx\n", fri.fri_Screen));
			DB (printf ("ColorMap      : 0x%lx\n", fri.fri_ColorMap));

			if ((fri.fri_PropertyFlags & DIPF_IS_HAM) ||
			    (fri.fri_PropertyFlags & DIPF_IS_EXTRAHALFBRITE))
			{
			    DB (printf ("HAM or ExtraHalfBrite\n"));
			}

			/* Layout the object on our process */
			gpl.MethodID = DTM_PROCLAYOUT;
			gpl.gpl_GInfo = NULL;
			gpl.gpl_Initial = 1;
			if (DoMethodA (o, &gpl))
			{
			    /* Get the object information */
			    GetDTAttrs (o,
					PDTA_ModeID, &modeid,
					PDTA_CRegs, &cregs,
					PDTA_NumColors, &numcolors,
					PDTA_BitMapHeader, &bmhd,
					PDTA_BitMap, &bm,
					TAG_DONE);

			    /* Make sure we have a bitmap to attach to the screen */
			    if (bm)
			    {
				/* Open the screen */
				if (scr = OpenScreenTags (NULL,
							  SA_Width, (ULONG) fri.fri_Dimensions.Width,
							  SA_Height, (ULONG) fri.fri_Dimensions.Height,
							  SA_Depth, (ULONG) fri.fri_Dimensions.Depth,
							  SA_DisplayID, modeid,
							  SA_Interleaved, TRUE,
							  SA_ShowTitle, FALSE,
							  SA_Quiet, TRUE,
							  SA_Behind, TRUE,
							  SA_BitMap, bm,
							  TAG_DONE))
				{
				    /* Load the color map */
				    if (cregs)
				    {
					numcolors = 2 << (scr->RastPort.BitMap->Depth - 1);
					DB (printf ("set %ld colors\n", numcolors));
					for (i = 0; i < numcolors; i++)
					{
					    r = cregs[i * 3 + 0];
					    g = cregs[i * 3 + 1];
					    b = cregs[i * 3 + 2];
					    SetRGB32 (&scr->ViewPort, i, r, g, b);
					}
				    }

				    /* Bring the screen to the front now */
				    ScreenToFront (scr);

				    printf ("Press ^C to abort\n");
				    Wait (SIGBREAKF_CTRL_C);

				    CloseScreen (scr);
				}
				else
				    printf ("couldn't open screen\n");
			    }
			    else
				printf ("no bitmap!\n");
			}
			else
			    printf ("couldn't layout picture\n");
		    }
		    else
			printf ("couldn't frame object\n");

		    /* Get rid of the object */
		    DisposeDTObject (o);
		}
		else
		    ShowError (IoErr ());
	    }
	    else
		printf ("couldn't open datatypes.library V39\n");

	    CloseLibrary (DataTypesBase);
	    CloseLibrary (GfxBase);
	    CloseLibrary (IntuitionBase);
	}
	else
	    printf ("couldn't open intuition.library V39\n");
    }
    else
	printf ("requires picture name\n");
}
