/*

interfaccia.c

Definisce gadgets e finestra per ITALIANE, inizializza tutto ed inizia il
colloquio dati con il programma.

*/

#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <libraries/ArpBase.h>
#include <functions.h>

#include "italiane.h"

#define CSF 35
#define CSS 14
#define CSX 10

extern struct GfxBase *GfxBase;

static struct Window *ww = NULL;

static UWORD w_larg = 0;
static UWORD w_altz = 0;
static UWORD fonth  = 0;
static UWORD fontmh = 0;

static char s_file[ CSF ];          /* "( CSF caratteri )"  + '\0' */
static char s_size[ CSS ];          /* "xxx.xxx bytes"      + '\0' */
static char s_status[ 9 ];          /* Filtrato | In corso  + '\0' */
static char s_39[ CSX ];            /* " ' = xxxx"          + '\0' */
static char s_96[ CSX ];            /* " ` = xxxx"          + '\0' */

static char s_load[] = { " Nuovo file " };
static char s_save[] = { " Salva file " };

static struct IntuiText t_file;
static struct IntuiText t_size;
static struct IntuiText t_status;
static struct IntuiText t_39;
static struct IntuiText t_96;
static struct IntuiText t_load;
static struct IntuiText t_save;

static struct Image i_load;
static struct Image i_save;

static struct Gadget g_load;
static struct Gadget g_save;

static struct Gadget *firstgad = NULL;
static int gadnum   = 0;

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

MSIZE: Ritorna la IntuiTextLength di un a stringa lunga m volte 'm'.

*/

SHORT MSIZE( m )
int m;

{
struct IntuiText tm;
UBYTE sm[ 255 ];
int c;

tm.FrontPen  = AUTOFRONTPEN;
tm.BackPen   = AUTOBACKPEN;
tm.DrawMode  = AUTODRAWMODE;
tm.LeftEdge  = 0;
tm.TopEdge   = 0;
tm.ITextFont = AUTOITEXTFONT;
tm.IText     = sm;
tm.NextText  = AUTONEXTTEXT;         /* Tanto e` = NULL */

for( c = 0 ; c < m ; c++ ) {
    sm[ c ] = (UBYTE)109;
    sm[ c+1 ] = (UBYTE)0;
} /* for */

return IntuiTextLength( &tm );

} /* Fine di MSIZE */

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

FSIZE: Ritorna il valore di n volte h. Usata con f = altezza font corrente.

*/

UWORD FSIZE( h , n )
UWORD h;
int n;

{
int c;
UWORD f = 0;

for( c = 0 ; c < n ; c++ )
    f = f + h;

return f;

} /* Fine di FSIZE */

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

AUTONOTIFY: Notifica i messaggi di errore con un AutoRequester.

*/

int AUTONOTIFY( titolo , messaggio )
char *titolo;
char *messaggio;

{
struct Window *arwp;
struct IntuiText ntxt;
struct IntuiText nmsg;
struct IntuiText Cont;
struct IntuiText Canc;

SHORT tle, mle, tte, mte;   /* txt | msg : LeftEdge & TopEdge */
UWORD arwl, arwa, arfh;     /* larghezza, altezza e font */
SHORT r;                    /* AutoReQuest RETurn code */

if ( ww ) {
    arwp = ww;
    arwl = ww->WScreen->Width;
    arfh = ww->WScreen->Font->ta_YSize + 2;
} /* if */
else {
    arwp = NULL;
    arwl = GfxBase->NormalDisplayColumns;
    arfh = GfxBase->DefaultFont->tf_YSize + 2;
} /* else */

/* arwl = (arwl >> 1 ); */

tle = MSIZE( 2 );
tte = arfh;

mle = tle;
mte = ( tte << 1 );

arwa = FSIZE ( arfh , 7 );

ntxt.FrontPen  = AUTOFRONTPEN;
ntxt.BackPen   = AUTOBACKPEN;
ntxt.DrawMode  = AUTODRAWMODE;
ntxt.LeftEdge  = tle;
ntxt.TopEdge   = tte;
ntxt.ITextFont = AUTOITEXTFONT;
ntxt.IText     = (UBYTE *)titolo;
ntxt.NextText  = &nmsg;

nmsg.FrontPen  = AUTOFRONTPEN;
nmsg.BackPen   = AUTOBACKPEN;
nmsg.DrawMode  = AUTODRAWMODE;
nmsg.LeftEdge  = mle;
nmsg.TopEdge   = mte;
nmsg.ITextFont = AUTOITEXTFONT;
nmsg.IText     = (UBYTE *)messaggio;
nmsg.NextText  = NULL;

Cont.FrontPen  = AUTOFRONTPEN;  /* SINISTRA = TRUE */
Cont.BackPen   = AUTOBACKPEN;
Cont.DrawMode  = AUTODRAWMODE;
Cont.LeftEdge  = AUTOLEFTEDGE;
Cont.TopEdge   = AUTOTOPEDGE;
Cont.ITextFont = AUTOITEXTFONT;
Cont.IText     = (UBYTE *)"Da capo";
Cont.NextText  = AUTONEXTTEXT;  /* Tanto e` = NULL */

Canc.FrontPen  = AUTOFRONTPEN;  /* DESTRA = FALSE */
Canc.BackPen   = AUTOBACKPEN;
Canc.DrawMode  = AUTODRAWMODE;
Canc.LeftEdge  = AUTOLEFTEDGE;
Canc.TopEdge   = AUTOTOPEDGE;
Canc.ITextFont = AUTOITEXTFONT;
Canc.IText     = (UBYTE *)"Termina";
Canc.NextText  = AUTONEXTTEXT;

/*lint -e516 */
r = AutoRequest( arwp, &ntxt, &Cont, &Canc, NULL, NULL, (long)arwl, (long)arwa );
/*lint +e516 */

return (int)r;

} /* Fine di AUTONOTIFY */

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

FLOAD: Setta tutto il necessario per NUOVO_FILE.

*/

void FLOAD( fp )
ICTB *fp;

{
static LFPB lp;
static char nuovonome[ CAR_PATH ];

fp->icb_command = CMD_NEWF;

fp->icb_er = ARPFREQ( nuovonome );

if ( fp->icb_er != AF_RIGHTSEL ) {
    fp->icb_command = CMD_NULL;
    return;
} /* if */

lp.lf_nome = &nuovonome[ 0 ];
lp.nome_vuoto = FALSE;
fp->icb_cpb = &lp;
fp->icb_crb = fp->icb_bufd;

} /* Fine di FLOAD */

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

BSAVE: Setta tutto il necessario per SALVA_BUFFER.

*/

void BSAVE( fp )
ICTB *fp;

{
static SFPB sp;
static char nuovonome[ CAR_PATH ];

if ( fp->icb_bust->bs_status == BS_VOID ) {
    fp->icb_command = CMD_NULL;
    return;
} /* if */

fp->icb_command = CMD_SAVE;

fp->icb_er = ARPFREQ( nuovonome );

if ( fp->icb_er != AF_RIGHTSEL ) {
    fp->icb_command = CMD_NULL;
    return;
} /* if */

sp.lf_nome = &nuovonome[ 0 ];
sp.nome_vuoto = FALSE;
fp->icb_cpb = &sp;
fp->icb_crb = fp->icb_bufd;

} /* Fine di BSAVE */

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

INIT_DISP: Inizializza i gadgets, static cosi` dovrebbero rimanere...

*/

static void INIT_DISP()

{
#define T_FPEN 2
#define T_BPEN 1
#define T_L_EDGE 0
#define T_T_EDGE 1
#define I_DEPTH  1
#define ID_FILT 1
#define ID_SAVE 2

SHORT le_file, te_file, le_size, te_size, le_status, te_status;
SHORT le_39, te_39, le_96, te_96;
SHORT gw_load, gw_save, gh_load, gh_save, x_load, x_save, y_load, y_save;

int c;
char *s_promptsize = " bytes";
char *s_prompt39   = " ' =  ";
char *s_prompt96   = " ` =  ";

/* sistemiamo le stringhe con i contenuti giusti */

for( c = 0 ; c < 6 ; c++ ) {
    s_size[ c+7 ]   = s_promptsize [ c ];
    s_39[ c ]       = s_prompt39[ c ];
    s_96[ c ]       = s_prompt96[ c ];
} /* for */

s_size[ CSS ] = '\0';

/* sistemiamo le coordinate per rendere il display font-relative */

le_file = MSIZE( 3 );
te_file = fonth + fontmh;   /* te_file = (SHORT)FSIZE( fonth , 2 ); */

t_file.FrontPen  = 1;
t_file.BackPen   = 0;
t_file.DrawMode  = JAM2;
t_file.LeftEdge  = le_file;
t_file.TopEdge   = te_file;
t_file.ITextFont = NULL;
t_file.IText     = (UBYTE *)s_file;
t_file.NextText  = &t_size;

le_size = le_file;
te_size = te_file << 1;                 /* (SHORT)( fonth << 2 ); */

t_size.FrontPen  = 1;
t_size.BackPen   = 0;
t_size.DrawMode  = JAM2;
t_size.LeftEdge  = le_size;
t_size.TopEdge   = te_size;
t_size.ITextFont = NULL;
t_size.IText     = (UBYTE *)s_size;
t_size.NextText  = &t_status;

le_status = le_size;
te_status = te_file + te_size;

t_status.FrontPen  = 1;
t_status.BackPen   = 0;
t_status.DrawMode  = JAM2;
t_status.LeftEdge  = le_status;
t_status.TopEdge   = te_status;
t_status.ITextFont = NULL;
t_status.IText     = (UBYTE *)s_status;
t_status.NextText  = &t_39;

/* w_larg = ( ( fonth << 2 ) + (UWORD)MSIZE( CSF ) ); */
/* w_altz = ( ( fonth << 4 ) + ( fonth << 1 ) ); commento: fonth * 10 */

w_larg = (UWORD)( MSIZE( 6 ) + MSIZE( CSF ) );
w_altz = fonth << 3;                /* FSIZE( fonth , 8 ); */

le_39 = w_larg - (UWORD)( MSIZE( CSX ) + MSIZE( 3 ) );
te_39 = te_size;

t_39.FrontPen  = 1;
t_39.BackPen   = 0;
t_39.DrawMode  = JAM2;
t_39.LeftEdge  = le_39;
t_39.TopEdge   = te_39;
t_39.ITextFont = NULL;
t_39.IText     = (UBYTE *)s_39;
t_39.NextText  = &t_96;

le_96 = le_39;
te_96 = te_status;

t_96.FrontPen  = 1;
t_96.BackPen   = 0;
t_96.DrawMode  = JAM2;
t_96.LeftEdge  = le_96;
t_96.TopEdge   = te_96;
t_96.ITextFont = NULL;
t_96.IText     = (UBYTE *)s_96;
t_96.NextText  = NULL;

/* ora inizializziamo i testi dei gadgets */

t_load.FrontPen  = T_FPEN;                      /* UBYTE */
t_load.BackPen   = T_BPEN;                      /* UBYTE */
t_load.DrawMode  = JAM1;                        /* UBYTE */
t_load.LeftEdge  = T_L_EDGE;                    /* SHORT */
t_load.TopEdge   = T_T_EDGE;                    /* SHORT */
t_load.ITextFont = NULL;                        /* struct TextAttr * */
t_load.IText     = (UBYTE *)s_load;             /* UBYTE * */
t_load.NextText  = NULL;                        /* struct IntuiText * */

t_save.FrontPen  = T_FPEN;
t_save.BackPen   = T_BPEN;
t_save.DrawMode  = JAM1;
t_save.LeftEdge  = T_L_EDGE;
t_save.TopEdge   = T_T_EDGE;
t_save.ITextFont = NULL;
t_save.IText     = (UBYTE *)s_save;
t_save.NextText  = NULL;

/* immagini nulle per i gadgets */

gw_load = (SHORT)IntuiTextLength(&t_load);
gw_save = (SHORT)IntuiTextLength(&t_save);
gh_load = gh_save = (SHORT)fonth;

i_load.LeftEdge   = 0;          /* SHORT */
i_load.TopEdge    = 0;          /* SHORT */
i_load.Width      = gw_load;    /* SHORT */
i_load.Height     = gh_load;    /* SHORT */
i_load.Depth      = I_DEPTH;    /* SHORT */
i_load.ImageData  = NULL;       /* USHORT */
i_load.PlanePick  = 0x0;        /* UBYTE */
i_load.PlaneOnOff = 0x0;        /* UBYTE */
i_load.NextImage  = NULL;       /* struct Image * */

i_save.LeftEdge   = 0; /* x_save; */
i_save.TopEdge    = 0; /* y_save; */
i_save.Width      = gw_save;
i_save.Height     = gh_save;
i_save.Depth      = I_DEPTH;
i_save.ImageData  = NULL;
i_save.PlanePick  = 0x0;
i_save.PlaneOnOff = 0x0;
i_save.NextImage  = NULL;

/*lint -e611 */

/* i gadgets, finalmente */

x_load = (SHORT)MSIZE( 3 );
y_load = (SHORT)( te_file * (-1) );

g_load.NextGadget    = &g_save;                      /* struct Gadget * */
g_load.LeftEdge      = x_load;                       /* SHORT */
g_load.TopEdge       = y_load;                       /* SHORT */
g_load.Width         = gw_load;                      /* SHORT */
g_load.Height        = gh_load;                      /* SHORT */
g_load.Flags         = GADGHCOMP|GADGIMAGE|GRELBOTTOM|SELECTED;
                                                     /* USHORT */
g_load.Activation    = GADGIMMEDIATE;                /* USHORT */
g_load.GadgetType    = BOOLGADGET;                   /* USHORT */
g_load.GadgetRender  = (APTR)&i_load;                /* APTR */
g_load.SelectRender  = NULL;                         /* APTR */
g_load.GadgetText    = &t_load;                      /* struct IntuiText * */
g_load.MutualExclude = 0;                            /* LONG */
g_load.SpecialInfo   = NULL;                         /* APTR */
g_load.GadgetID      = ID_FILT;                      /* USHORT */
g_load.UserData      = (void *)FLOAD;                /* APTR */

x_save = ( ( IntuiTextLength( &t_save ) + MSIZE( 3 ) ) * (-1) );
y_save = y_load;

g_save.NextGadget    = NULL;
g_save.LeftEdge      = x_save;
g_save.TopEdge       = y_save;
g_save.Width         = gw_save;
g_save.Height        = gh_save;
g_save.Flags         = GADGHCOMP|GADGIMAGE|GRELRIGHT|GRELBOTTOM|SELECTED;
g_save.Activation    = GADGIMMEDIATE;
g_save.GadgetType    = BOOLGADGET;
g_save.GadgetRender  = (APTR)&i_save;
g_save.SelectRender  = NULL;
g_save.GadgetText    = &t_save;
g_save.MutualExclude = 0;
g_save.SpecialInfo   = NULL;
g_save.GadgetID      = ID_SAVE;
g_save.UserData      = (void *)BSAVE;

/*lint +e611 */

firstgad = &g_load;
gadnum = ID_SAVE;    /* numero tot gadgets usati = ID ultimo gadget */

} /* Fine di INIT_DISP */

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

FINESTRA: Apre la finestra di output del programma.

          Invoca: INIT_DISP
*/

int FINESTRA( t )
char *t;

{
#define MODULO_F "Funzione di apertura window"
#define E_NOWIN "ERRORE: Fallita apertura finestra principale."

struct NewWindow nw;

UWORD s_larg, s_altz;
SHORT le_offset, te_offset;

s_larg = GfxBase->NormalDisplayColumns;
s_altz = GfxBase->NormalDisplayRows;
fonth  = GfxBase->DefaultFont->tf_YSize + 2;
fontmh = ( fonth >> 1 );

INIT_DISP();

le_offset = ( (s_larg - w_larg) >> 1 );
te_offset = ( (s_altz - w_altz) >> 1 );

nw.LeftEdge    = le_offset;
nw.TopEdge     = te_offset;
nw.Width       = w_larg;
nw.Height      = w_altz;
nw.DetailPen   = (UBYTE)-1;
nw.BlockPen    = (UBYTE)-1;
nw.IDCMPFlags  = CLOSEWINDOW|GADGETDOWN|REFRESHWINDOW;
nw.Flags       = ACTIVATE|WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|SMART_REFRESH;
nw.FirstGadget = firstgad;
nw.CheckMark   = NULL;
nw.Title       = (UBYTE *)t;
nw.Screen      = NULL;
nw.BitMap      = NULL;
nw.MinWidth    = 0;
nw.MinHeight   = 0;
nw.MaxWidth    = 0;
nw.MaxHeight   = 0;
nw.Type        = WBENCHSCREEN;

ww = (struct Window *)OpenWindow( &nw );

if ( !ww ) {
    INFO_SET( MODULO_F , E_NOWIN );
    return 1;
} /* if */

return 0;

} /* Fine di FINESTRA */

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

AGGIORNA: Aggiorna il display con i dati della BUST.

*/

int AGGIORNA( ab )
BUST *ab;

{
char a_temp[ 7 ];
char *ast_done = "Filtrato";
char *ast_proc = "In corso";
char *ast_void = "Vuoto";

SPrintf( s_file , "%s" , ab->bs_nome );

switch( ab->bs_status ) {
    case BS_DONE :
        SPrintf( s_status, "%-9s" , ast_done );
        break;

    case BS_PROC :
        SPrintf( s_status, "%-9s" , ast_proc );
        break;

    case BS_VOID :
        SPrintf( s_status, "%-9s" , ast_void );
        break;

} /* switch */

SPrintf( a_temp , "%06ld" , ab->bs_size );

s_size[ 0 ] = a_temp[ 0 ];
s_size[ 1 ] = a_temp[ 1 ];
s_size[ 2 ] = a_temp[ 2 ];
s_size[ 3 ] = '.';
s_size[ 4 ] = a_temp[ 3 ];
s_size[ 5 ] = a_temp[ 4 ];
s_size[ 6 ] = a_temp[ 5 ];

SPrintf( a_temp , "%04d" , ab->bs_tot39 );

s_39[ 5 ] = a_temp[ 0 ];
s_39[ 6 ] = a_temp[ 1 ];
s_39[ 7 ] = a_temp[ 2 ];
s_39[ 8 ] = a_temp[ 3 ];
s_39[ 9 ] = '\0';

SPrintf( a_temp , "%04d" , ab->bs_tot96 );

s_96[ 5 ] = a_temp[ 0 ];
s_96[ 6 ] = a_temp[ 1 ];
s_96[ 7 ] = a_temp[ 2 ];
s_96[ 8 ] = a_temp[ 3 ];
s_96[ 9 ] = '\0';

/*lint -e516 */
PrintIText( ww->RPort , &t_file , 1L , 1L );
/*lint +e516 */

RefreshGList( firstgad , ww , NULL , gadnum );

return 0;

} /* Fine di AGGIORNA */

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

INTERF_INIT: Inizializza il necessario per l'interfacciamento, apre
             finestre e gadgets vari e ritorna.

*/

int INTERF_INIT( s )
char *s;

{
int ir;
BUST ii;
char *istr = "ITALIANE © P.Sommaruga, Aug 1991";

ir = FINESTRA( s );

if ( ir )   return ir;

SPrintf( ii.bs_nome , "%s" , istr );
ii.bs_size = 0L;
ii.bs_tot39 = 0;
ii.bs_tot96 = 0;
ii.bs_status = BS_VOID;

ir = AGGIORNA( &ii );

return ir;

} /* FINE DI INTERF_INIT */

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

CHIUDI_INTERF: Chiude e dealloca le cose che la interfaccia ha reso per
               se` all'insaputa del programma principale.

*/

void CHIUDI_INTERF()

{

if ( ww ) {
    CloseWindow( ww );
    ww = NULL;
} /* if */

} /* Fine di CHIUDI_INTERF */

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

Gestisce il sistema, riempie i campi opportuni di un ICTB e ritorna.

*/

void INTERFACCIA( ipb )
ICTB *ipb;

{
struct IntuiMessage *msg;
ULONG class;
struct Gadget *gad;
void (*funz)();                 /* funzione puntata nel gadget */
int ant;

/*lint -e516 -e534 */

for( ;; ) {
    if ( ipb->icb_er ) {
        ant = INFORMA( AUTONOTIFY );

        if ( ant ) {
            ipb->icb_command = CMD_RSTRT;
            ipb->icb_er = 0;
        } /* if */
        else {
            while( msg = (struct IntuiMessage *)GetMsg( ww->UserPort) )
                ReplyMsg( msg );
            CHIUDI_INTERF();
            ipb->icb_command = CMD_CLOSE;
        } /* else */

        return;

    } /* if */

    AGGIORNA( ipb->icb_bust );

    Wait( (long)1<<ww->UserPort->mp_SigBit );

    while( msg = (struct IntuiMessage *)GetMsg( ww->UserPort ) ) {
        class = msg->Class;
        gad = (struct Gadget *)msg->IAddress;
        funz = (void *)gad->UserData;
        ReplyMsg( msg );

        switch( class ) {

            case CLOSEWINDOW :
                while( msg = (struct IntuiMessage *)GetMsg( ww->UserPort) )
                    ReplyMsg( msg );
                CHIUDI_INTERF();
                ipb->icb_command = CMD_CLOSE;
                return;

            case GADGETDOWN :
                (*funz)( ipb );
                return;

            default : return;

        } /* switch class */
    } /* while */
} /* for */

/*lint +e516 +e534 */

} /* Fine di INTERFACCIA */

