/** Extended String Gadget Test Program :ts=8 **/

/*
Copyright (c) 1989 Commodore-Amiga, Inc.

Executables based on this information may be used in software
for Commodore Amiga computers. All other rights reserved.
This information is provided "as is"; no warranties are made.
All use is at your own risk, and no liability or responsibility
is assumed.
*/

#include <exec/types.h>
#include <intuition/intuition.h>
#include <intuition/sghooks.h>
#include <utility/hooks.h>

#include <clib/intuition_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/exec_protos.h>

#include <string.h>
#include <stdlib.h>

#include "strgad.h"

struct  Window      *getNewWind();
struct  Screen      *getNewScreen();

struct  IntuitionBase   *IntuitionBase = NULL;
struct  GfxBase         *GfxBase = NULL;
APTR    DiskfontBase = NULL;

ULONG   flg = WINDOWCLOSE | NOCAREREFRESH | WINDOWDRAG
    | WINDOWDEPTH | SIMPLE_REFRESH;

ULONG   iflg = GADGETUP | CLOSEWINDOW;

struct SGSpec sgadspec[] = {
    {NULL, 0, 200, 20, 250, "long cent. SG", "FooBar", 215, STRINGCENTER, 0},
    {NULL, 0, 200, 20, 250, "short cent. (cycle!)","FooBar",15,STRINGCENTER,1},
    {NULL, 0, 200, 20, 250, "long left SG", "FooBar", 215, 0, 2},
    {NULL, 0, 200, 20, 250, "short left SG", "FooBar", 15, 0, 3},
    {NULL, 0, 200, 20, 250, "short right SG", "FooBar", 15, STRINGRIGHT, 4},
    {NULL, 0, 200, 20, 250, "long right SG", "FooBar", 215, STRINGRIGHT, 5},
};

#define NUMSGS	( sizeof ( sgadspec ) / sizeof (struct SGSpec) )
#define SGSEX( gadget )	\
		(( (struct StringInfo *) (gadget)->SpecialInfo)->Extension)

struct Gadget	*sgarray[ NUMSGS ];	/* used for cycling active gadget	*/

struct TextAttr propta = { (UBYTE *) "ruby.font", 12, 0, 0 };
struct TextAttr testa = { (UBYTE *) "ruby.font", 8, 0, 0 };

UBYTE	workbuff[ 216 ];

extern struct Hook	tabhook;
extern struct Hook	cyclehook;

struct StringExtend tabsex = { NULL, {3, 1}, {1, 3}, 0, &tabhook, workbuff, };
struct StringExtend cyclesex = { NULL, {3, 1}, {1, 3}, 0, &cyclehook, workbuff};

main()
{
    struct  IntuiMessage	*msg;
    struct Screen   	*screen = NULL;
    struct Window   	*window = NULL;
    WORD    		exitval = 0;
    int			gadgid;

    struct Gadget	*sgad;
    struct Gadget	*g;
    int			topskip;
    int			sgx;
    int			sgtop;
    struct RastPort	*screenrport;
    struct TextFont	*propfont = NULL;
    struct TextFont	*testfont = NULL;

    /* hold data from *msg  */
    ULONG   		class;
    USHORT  		code;
    APTR    		iaddr;

    if ((IntuitionBase = 
	(struct IntuitionBase *) OpenLibrary("intuition.library", 36L)
	) == NULL)
    {
	printf("NO INTUITION LIBRARY\n");
	exitval = 1;
	goto EXITING;
    }

    if ((GfxBase = 
	(struct GfxBase *) OpenLibrary("graphics.library", 36L)
	) == NULL)
    {
	printf("NO GRAPHICS LIBRARY\n");
	exitval = 2;
	goto EXITING;
    }

    if ((DiskfontBase = 
	(APTR) OpenLibrary("diskfont.library", 0L)
	) == NULL)
    {
	printf("NO DISKFONT LIBRARY\n");
	exitval = 3;
	goto EXITING;
    }

    propfont = OpenDiskFont( &propta );
    testfont = OpenDiskFont( &testa );

    printf("propfont: %lx\n", propfont );
    printf("testfont: %lx\n", testfont );

    screen = getNewScreen( &propta );
    if (!screen) 
    {
	printf("No screen.\n");
	goto EXITING;
    }

    /* init libraries and window    */
    window = getNewWind(21, 20, 500, 150, screen, flg, iflg);
    if (window == NULL)
    {
	exitval = 1;
	goto EXITING;
    }

    screenrport = &window->WScreen->RastPort;

    sgtop = 20;
    topskip = SGHEIGHT( screenrport ) +  BORDERGAP;
    /* ZZZ: check they fit	*/

    for ( sgx = 0; sgx < NUMSGS; sgx++ )
    {
	sgadspec[ sgx ].sgs_RPort = screenrport;
	sgadspec[ sgx ].sgs_TxHeight = screenrport->TxHeight;
	sgadspec[ sgx ].sgs_Top = sgtop;
	sgtop += topskip;
    }

    sgad = getStringGadgets( sgadspec, NUMSGS );

    tabsex.Font = testfont;
    cyclesex.Font = testfont;

    initMyHooks();	/* set up my hook interface	*/

    if ( sgad )
    {
	for ( g = sgad, sgx = 0; g && sgx < NUMSGS; ++sgx, g = g->NextGadget)
	{
	    g->Activation |= STRINGEXTEND;

            sgarray[ sgx ] = g;	/* stash pointer to gadget for cycling */

	    /* string gadget number 1 (second in list) is special */
	    SGSEX( g ) = ( sgx == 1 )? &cyclesex: &tabsex;
	}
	
	AddGList( window, sgad, (LONG) -1, (LONG) NUMSGS, NULL );
	RefreshGList( sgad, window, NULL, (LONG) NUMSGS );
    }

    printf("test program ok\n");

    FOREVER
    {
	if ((msg = (struct IntuiMessage *)GetMsg(window->UserPort)) == NULL)
	{
	    Wait(1L<<window->UserPort->mp_SigBit);
	    continue;
	}

	/* Stash message contents and reply,
	 * important when message triggers some
	 * lengthy processing
	 */

	class   = msg->Class;
	code    = msg->Code;
	iaddr   = msg->IAddress;
	ReplyMsg(msg);

	switch (class)
	{
	case GADGETUP:
	    gadgid = ((struct Gadget *) iaddr)->GadgetID;


	    if  ( code == MYCODETAB )
	    {
		ActivateGadget( sgarray[ (gadgid + 1)% NUMSGS], window, NULL);
	    }
	    else if ( code == MYCODEBACKTAB )
	    {
		ActivateGadget( sgarray[ (gadgid + (NUMSGS-1) ) % NUMSGS ],
		    window, NULL);
	    }
	    break;


	case CLOSEWINDOW:
	    goto EXITING;

	}
    }

EXITING:
    if (window)
    {
	RemoveGList( window, sgad, NUMSGS );
	freeStringGadgets( sgad, NUMSGS );
	CloseWindow(window);
    }
    if (screen)
    {
	CloseScreen( screen );
    }
    if (propfont) CloseFont( propfont );
    if (DiskfontBase) CloseLibrary(DiskfontBase);
    if (GfxBase) CloseLibrary(GfxBase);
    if (IntuitionBase) CloseLibrary(IntuitionBase);
    /** FIX: FreeRemember() */
    exit (exitval);
}


struct  Window * getNewWind(left, top, width, height, screen, flg, iflg)
SHORT   left, top, width, height;
struct Screen	*screen;
ULONG   flg, iflg;
{
    struct  Window  *OpenWindow();
    struct  NewWindow   nw;

    nw.LeftEdge =   (SHORT) left;
    nw.TopEdge  =   (SHORT) top;
    nw.Width    =   (SHORT) width;
    nw.Height   =   (SHORT) height;
    nw.DetailPen    =   (UBYTE) -1;
    nw.BlockPen =   (UBYTE) -1;
    nw.IDCMPFlags   =   (ULONG) iflg;

    nw.Flags    =   (ULONG) flg;

    nw.FirstGadget  =   (struct Gadget *)   NULL;
    nw.CheckMark    =   (struct Image *)    NULL;
    nw.Title    =   (UBYTE *)   " New Window ";
    nw.Screen   =   screen;
    nw.BitMap   =   (struct BitMap *)   NULL;
    nw.MinWidth =   (SHORT) 50;
    nw.MinHeight=   (SHORT) 30;
    /* work around bug  */
    nw.MaxWidth =   (SHORT) nw.Width;
    nw.MaxHeight    =   (SHORT) nw.Height;
    nw.Type     =   (USHORT) CUSTOMSCREEN;

    return ((struct Window *) OpenWindow(&nw));
}

/** get a new screen	**/

struct TextAttr SafeFont = { (UBYTE *) "topaz.font", 8, 0, 0, };

struct	Screen	*getNewScreen(textattr)
struct TextAttr	*textattr;
{
    struct	NewScreen	ns;

    ns.LeftEdge	=	0;
    ns.TopEdge	=	0;
    ns.Width	=	STDSCREENWIDTH;
    ns.Height	=	STDSCREENHEIGHT;
    ns.Depth	=	2;	/* 4 colors	*/
    ns.DetailPen =	0;
    ns.BlockPen	=	1;
    ns.ViewModes =	HIRES;	/* determined above	*/
    ns.Type		=	CUSTOMSCREEN;
    ns.Font		=	textattr? textattr: &SafeFont;
    ns.DefaultTitle	=	(UBYTE *) " Test Screen ";
    ns.Gadgets	=	NULL;
    ns.CustomBitMap	=	NULL;

    return ((struct Screen *) OpenScreen(&ns));
}

