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

Programma ...... Jask.c
Versione ....... 1.0i, Agosto 1989
Autore ......... J. Barshinger, I2(EYE) Systems
Funzione ....... Sostituzione Intuitionizzata di Ask standard
Sintassi ....... Jask -r [-q] [-p] [-n] [-t] [-d]
Hardware ....... Amiga 512K, Kickstart & Workbench V1.2/V1.3
Software ....... Lattice C Compiler V5.02 (Aztec NO!)
Note ........... Traduzione ed adattamento di Luigi R. Callegari

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

#include "intuition/intuition.h"
#include "string.h"
#include "stdlib.h"
#include "ctype.h"
#include "stdio.h"
#include "proto/exec.h"
#include "proto/intuition.h"
#include "proto/dos.h"

#define POS_GAD   TRUE
#define NEG_GAD   TRUE

/* La prima struttura definisce il set di caratteri standard in
corsivo, il secondo in modo normale **************************/

struct TextAttr ScreenFont1 = {
 "topaz.font", TOPAZ_EIGHTY, FSF_ITALIC, FPF_ROMFONT };

struct TextAttr ScreenFont2 = {
 "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT };

/* Stringhe di testo dei gadget positivo, negativo e di richiesta
****************************************************************/

char RText[] = "                                        ";
char PText[] = "            ";
char NText[] = "            ";

/* Strutture di definizione dei testi dei gadget e requester */

struct IntuiText ReqText = {
 3, 2, JAM2, 0, 0, &ScreenFont1, RText, NULL }; 

struct IntuiText ReqText1 = {
 1, 2, JAM1, 2, 5, &ScreenFont2, PText, NULL
};

struct IntuiText ReqText2 = {
 1, 2, JAM1, 2, 5, &ScreenFont2, NText, NULL
};

/* Coordinate dei punti usati per tracciare i rettangoli intorno ai
gadget. ******************************************************** */

short DefGadBorderPts[] = { 
 -1, -6, -7, -1, -7, 20, 
 -1, 25, 100, 25, 106, 20, 106, -1, 100, -6,
 -1, -6, -1, 25, -1, 20, 100, 20, 100, 25,
 100, -6, 100, -1, -1, -1
};
 
short aGadBorderPts[] = {
 -1, -1, 100, -1, 100, 20, -1, 20, -1, -1
};

short bGadBorderPts[] = {
 -4, -3, 103, -3, 103, 22, -4, 22,-4, -3
};

/* Dati di definizione dei bordi dei gadget ******/

struct Border NormGadBorder = {
 0, 0, 2, 3, JAM1, 5, bGadBorderPts, NULL }; 

struct Border GadBorder1 = {
 0, 0, 2, 3, JAM1, 5, aGadBorderPts, &NormGadBorder
};
struct Border GadBorder2 = {
 0, 0, 2, 3, JAM1, 5, aGadBorderPts, &NormGadBorder
};

/* Strutture di definizione dei gadget */

struct Gadget ReqGad2 = {
 NULL, 500, 10, 100, 20, GADGHCOMP,
 RELVERIFY, BOOLGADGET, (APTR)(&GadBorder2),
 NULL, &ReqText2, NULL, NULL, NEG_GAD, NULL
};

struct Gadget ReqGad1 = {
 &ReqGad2, 40, 10, 100, 20, GADGHCOMP,
 RELVERIFY, BOOLGADGET, (APTR)(&GadBorder1),
 NULL, &ReqText1, NULL, NULL, POS_GAD, NULL
};

/* Struttura di definizione dello schermo ************/

struct NewScreen ReqScreen = {
 0, 210, 640, 53, 2, 2, 3, 
 HIRES, CUSTOMSCREEN, &ScreenFont2, 
 (UBYTE *)"JRBII's Ask Requester V1.0i",  NULL
};

/* Struttura di definizione della finestra ***********/

struct NewWindow ReqWindow = {
 0, 10, 640, 43, -1, -1, 
 GADGETUP, ACTIVATE, &ReqGad1, NULL, 
 NULL, NULL, NULL, 0, 0, 0, 0, 
 CUSTOMSCREEN
};

/* ******************* Puntatori globali ***************/

struct Window *ReqWin = NULL;
struct Screen *ReqScr = NULL;
struct IntuitionBase *IntuitionBase = NULL;
struct IntuiMessage *msg; 
LONG result; 
int timeout; 

/* Done(void) è usata per concludere il programma in caso di
errori od al termine dell'esecuzione. Si noti che si risponde
ad eventuali messaggi in sospeso da Intuition e si chiudono solo
gli elementi aperti tramite degli if **************************/

void Done( void )
{

 if ( msg != 0 ) ReplyMsg((struct Message *) msg );
 if ( ReqWin ) CloseWindow((struct Window *) ReqWin );
 if ( ReqScr ) CloseScreen((struct Screen *) ReqScr );
 if ( IntuitionBase ) CloseLibrary((struct Library *)IntuitionBase);
 exit( result );
} 

/* Scandisce la linea di comando e fissa l'effetto di visualizzazione
desiderato. La routine è stata ridotta il più possibile per contenere
al massimo la dimensione del codice eseguibile finale. *************/

void Parse_Args(int argc, char *argv[])
{
 char i, k, x, y, error, rfound, pfound, nfound, *arg;
 
 error = 0;
 rfound = pfound = nfound = FALSE;
 
 for ( i = 1; i < argc ; i++ )
 {
   arg = argv[ i ];
 
   if ( arg[ 0 ] != '-') error++;
 
   switch ( tolower(arg[ 1 ]) )
   {
      case 'q': /* Rapido, schermo subito in posizione */
         ReqScreen.TopEdge = 146; 
         break;

      case 'r': /* Parametro testo requester */
         if ( !rfound )
            {
            rfound = TRUE; 
            if ((k = strlen(&arg[2])) > 40)
            k = 40;
            x = (40 - k) / 2; /* Centra testo */
            /* Copia testo nell'array di requester */
            for ( y = 2; y < k + 2 ; x++, y++ )
               RText[x] = arg[y];
            };
         break;
 
      case 'p': /* Testo gadget positivo */
         if ( !pfound )
            {
            pfound = TRUE;
            if (( k = strlen(&arg[2]) ) > 12)
               k = 12;
            x = (12 - k) / 2; /* Centra testo */

            for (y = 2; y < k+2; x++, y++)
               PText[x] = arg[y];
            };
         break;

      case 'n': /* Testo gadget negativo */
         if ( !nfound )
            {
            nfound = TRUE;

            if ( ( k = strlen(&arg[2]) ) > 12)
               k = 12;
            x = (12 - k) / 2; /* Centra testo */

            for (y = 2; y < k+2; x++, y++)
               NText[x] = arg[y];
            };
         break;

      case 't': /* Parametro di timeout */
         stcd_i(&arg[2],&timeout);
         timeout *= 10;
         ReqWindow.IDCMPFlags = GADGETUP|INTUITICKS;
         break;

      case 'd': /* Specifica default */
         if ( tolower( arg[2] ) == 'n')
         {
            GadBorder2.Count = 16; /* 16 coordinate */
            GadBorder2.XY = DefGadBorderPts; 
            GadBorder2.NextBorder = NULL;
            result = 0; 
         }
         else if (tolower(arg[2]) == 'p') 
         {
            GadBorder1.Count = 16; /* 16 coordinate */
            GadBorder1.XY = DefGadBorderPts;
            GadBorder1.NextBorder = NULL;
            result = 5; 
         }
         else error++; 
         break;

      default: 
         error++;
         break;
   }; /* Switch() */
 }; /* for() */
 
 if (!pfound) /* Se manca testo positivo, usa Si! */
 {
   PText[ 5 ] = 'S';
   PText[ 6 ] = 'I';
 };

 if (!nfound) /* Se manca testo negativo, usa No! */
 {
   NText[ 5 ] = 'N';
   NText[ 6 ] = 'O';
 };

 if ( error || ( !rfound ) ) 
 { 
   puts("USO: Jask -r [-q] [-p] [-n] [-t] [-d]");
   exit( 10L ); 
 };
 
}

void main( int argc, char *argv[] )
{
 struct Gadget *Gad; /* Messaggio dal gadget */
 short GadID;        /* Identificatore gadget */
 int time;           /* Numero di ticks da partenza */
 char i;
 
 time = 0;           /* Azzera tempo */
 result = 0;         /* Risultato di default = 0 */

 Parse_Args(argc, argv); /* Ricava argomenti */
 
 if (!(IntuitionBase = OpenLibrary("intuition.library",0L)))
   exit( 10L );

 if ((ReqScr = OpenScreen( &ReqScreen )) == NULL)
 {
   puts("Non si apre lo schermo di richiesta\n");
   result = 10;
   Done();
 };

 /* Poniamo indirizzo finestra in schermo */
 ReqWindow.Screen = ReqScr; 
 
 if ((ReqWin = OpenWindow(&ReqWindow)) == NULL)
 {
   puts("Non si apre la finestra di richiesta\n");
   result = 10;
   Done();
 };
 
 PrintIText(ReqWin->RPort,&ReqText,160,15);

 /* Fa scorrere lo schermo, se non si è specificato -q */

 for ( i=0 ; ( (i<64) && (ReqScreen.TopEdge > 200) ) ; i++ )
   MoveScreen(ReqScr, 0, -1);

 FOREVER /* Cicla per sempre, sino a tempo finito o GADGETUP */
 {
   WaitPort( ReqWin->UserPort ); /* Attende messaggio *****/

   msg = (struct IntuiMessage *) GetMsg(ReqWin->UserPort);

 while ( msg != 0 ) /* Cicla per tutti i messaggi */
 { 
   switch ( msg->Class ) /* Agisce in base al messaggio */
   {
      case GADGETUP:    /* Selezionato gadget **********/
         /* Ricaviamo indirizzo gadget e quale è stato selezionato */
         Gad = (struct Gadget *)(msg->IAddress);
         GadID = Gad->GadgetID;

         if (GadID)  /* Selezionato gadget positivo */
            result = 5;
         else        /* Selezionato gadget negativo */
            result = 0;
         Done();
         break;

      case INTUITICKS:  /* Messaggio dal timer *********/
         if (time++ > timeout) Done();
            break;
   }
 
 ReplyMsg( (struct Message *) msg ); /* Dealloca messaggio */

 msg = (struct IntuiMessage *) GetMsg(ReqWin->UserPort);
 
 } /* while */
 } /* FOREVER */
} /* main */
