/*
 * Print.c :
 * ---------
 * Auteur        : Xavier Mertens
 * Version       : 2
 * Révision      : 01A
 * Langage       : Lattice C v5.0
 * Compatibilité : 2.x
 * Description   : Impression de fichiers ASCII avec options.
 *                  v1.30 : - Compatibilité OS 2.0
 *                          - Fixer Topaz/9 comme fonte par défaut.
 *                          - Implantation du requester de la ARP.library
 *                  v1.30A: - Implantation du requester de la ASL.library.
 *                            (à la place du requester ARP)
 *                          - Ajout du gadget 'Pause'
 *                  v1.31A: - Supression de la fenêtre durant l'impression.
 *                  v1.32A: - Correction d'un sérieux bug.
 *                            Ajout de la routine TabToSpace();
 *                  v2.00A: - Adaptation pour le Workbench.
 *                  v2.01A: - Ajout d'une aide en ligne.
 * Remarques     : Compiler avec l'option '-b0'
 */

#include <stdio.h>
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfxbase.h>
#include <libraries/dosextens.h>
#include <workbench/workbench.h>
#include <workbench/startup.h>

#include "error_codes.h"    /* Définitions des codes d'erreur */

#define VERSION    "2.01A"
#define OS_VERSION 36
#define FONT       "topaz.font"
#define BGAD       22
#define TGAD       12
#define DATE       (&(FIBlock->fib_Date))
#define SIZE       (FIBlock->fib_Size)
#define NAME       (FIBlock->fib_FileName)
#define COMM       (FIBlock->fib_Comment)
#define PLEN       (Prefs.PaperLength)
#define SEL(n)     (BGad[n].Flags&SELECTED)
#define PRINT(x)   Write(Output(),(x),strlen(x))
#define RP         win->RPort
#define PRIORITE   -5

char *Jour[7]={
  (STRPTR)"Samedi",
  (STRPTR)"Dimanche",
  (STRPTR)"Lundi",
  (STRPTR)"Mardi",
  (STRPTR)"Mercredi",
  (STRPTR)"Jeudi",
  (STRPTR)"Vendredi"
};
char *Mois[12]={
  (STRPTR)"Janvier",
  (STRPTR)"Février",
  (STRPTR)"Mars",
  (STRPTR)"Avril",
  (STRPTR)"Mai",
  (STRPTR)"Juin",
  (STRPTR)"Juillet",
  (STRPTR)"Août",
  (STRPTR)"Septembre",
  (STRPTR)"Octobre",
  (STRPTR)"Novembre",
  (STRPTR)"Décembre"
};
char *GadgetText[BGAD]={
  (STRPTR)"         Nom",
  (STRPTR)" Commentaire",
  (STRPTR)"        Date",
  (STRPTR)"       Heure",
  (STRPTR)"      Octets",
  (STRPTR)"        Mots",
  (STRPTR)"      Lignes",
  (STRPTR)"       Pages",
  (STRPTR)"Entête Ligne",
  (STRPTR)" Bas de Page",
  (STRPTR)"Marge Gauche",
  (STRPTR)"Ligne / Page",
  (STRPTR)"  Pagination     <    ^    >",
  (STRPTR)"         NLQ",(STRPTR)"     Elite",
  (STRPTR)"    Condensé",(STRPTR)"     Mini",
  (STRPTR)"    Italique",(STRPTR)"     Gras",
  NULL,NULL,NULL
};
char *Style[6]={    /* Séquence ESCAPE à envoyer à l'imprimante :  */
  (STRPTR)"2\"z",  /* NLQ      */
  (STRPTR)"2w",     /* Elite    */  
  (STRPTR)"4w",     /* Condensé  */
  (STRPTR)"2v",     /* Mini      */
  (STRPTR)"3m",     /* Italique  */
  (STRPTR)"1m"      /* Gras      */
};
TEXT OutPut[31],              /* Sortie (par défaut PRT:)          */
     UndoBuffer[201],          /* Buffer pour les gadgets          */
     TextBuffer[TGAD][201];    /* Buffer pour les lignes de texte  */
char *File[51];
char *FBuffer=NULL;
static SHORT ZpS,
             ZGes,
             LNr,
             NoReq=1;      /* Par défaut: pas de requester */
static SHORT xb[BGAD]={    /* Abscisse des différents gadgets BOOL */
  10,10,10,10,10,10,10,10,250,250,250,250,250,
  250,358,250,358,250,358,278,318,358
};
static SHORT yb[BGAD]={    /* Ordonnées des différents gadgets BOOL */
  15,28,41,54,67,80,93,106,15,28,41,54,67,
  80,80,93,93,106,106,67,67,67
};
static SHORT xt[TGAD]={    /* Abscisse des différents gadgets STRING */
  140,140,140,140,140,140,140,140,380,380,380,380
};
static SHORT MTage[12]={  /* Ordonnées des différents gadgets STRING */
  31,28,31,30,31,30,31,31,30,31,30,31
};
static SHORT BGadPairs[2][6]={
  0,10,20,10,20,0,0,10,0,0,20,0
};
static SHORT TGadPairs[10]={
  0,0,103,0,103,10,0,10,0,0   /* 100 - 101 */
};
static struct TextAttr MyFont={
  FONT,                      /* Font Name                 */
  TOPAZ_EIGHTY,              /* Font Height               */
  FS_NORMAL,                 /* Style                     */
  FPF_ROMFONT                /* Preferences               */
};
static struct Border BGadBorder[4]={            /* Définition des borders  */
  0,0,2,0,JAM1,3,BGadPairs[0],NULL,            /* pour obtenit un effet   */
  0,0,1,0,JAM1,3,BGadPairs[1],&BGadBorder[0],  /* 3D                      */
  0,0,2,0,JAM1,3,BGadPairs[1],NULL,
  0,0,1,0,JAM1,3,BGadPairs[0],&BGadBorder[2]
};
static struct Border TGadBorder={
  -3,-2,1,0,JAM1,5,TGadPairs,NULL
};
static struct Border PGadBorder[2]={
  0,0,1,0,JAM1,5,TGadPairs,NULL,
  0,0,2,0,JAM1,5,TGadPairs,NULL
};
static struct IntuiText IText[BGAD],PrText={
  1,0,JAM1,12,2,&MyFont,(STRPTR)"Print file",NULL,
};
/*** INFOS GADGET ***/
static struct IntuiText Info={
  1,0,JAM1,12,2,&MyFont,(STRPTR)"  Infos!  ",NULL,
};
static struct IntuiText Pause={
  1,0,JAM1,8,2,&MyFont,(STRPTR)"   Pause  ",NULL,
};
static struct IntuiText EndText={
  1,0,JAM1,16,10,&MyFont,(STRPTR)"   Impression terminée   ",NULL
};
static struct IntuiText RText={
  1,0,JAM1,16,10,&MyFont,(STRPTR)"Préparez la page suivante",NULL
};
static struct IntuiText RGText[2]={
  1,0,JAM1,5,3,&MyFont,(STRPTR)"Continue",NULL,
  1,0,JAM1,5,3,&MyFont,(STRPTR)"Stoppe",NULL
};
static struct StringInfo SInfo[TGAD];

/*** Définition du BORD 3D pour les gadgets 'FILEPRINT' et 'INFOS!' ***/

static SHORT DPairs[2][6]={
  0,11,103,11,103,0,0,11,0,0,103,0
};
static struct Border DBorder[4]={
  0,0,1,0,JAM1,3,DPairs[0],NULL,
  0,0,2,0,JAM1,3,DPairs[1],&DBorder[0],
  0,0,1,0,JAM1,3,DPairs[1],NULL,
  0,0,2,0,JAM1,3,DPairs[0],&DBorder[2]
};
static struct Gadget BGad[BGAD],TGad[TGAD]={
  NULL,27,123,100,10,GADGHIMAGE,RELVERIFY,BOOLGADGET,
  (APTR)&PGadBorder[0],(APTR)&PGadBorder[1],&PrText,0,
  NULL,34,NULL
};
/*** FILEPRINT GADGET ***/
static struct Gadget PGad={
  NULL,27,123,100,10,GADGHIMAGE,RELVERIFY,BOOLGADGET,
  (APTR)&DBorder[1],(APTR)&DBorder[3],&PrText,0,
  NULL,34,NULL
};
/*** INFOS GAGDET ***/
static struct Gadget IGad={
  NULL,137,123,100,10,GADGHIMAGE,RELVERIFY,BOOLGADGET,
  (APTR)&DBorder[1],(APTR)&DBorder[3],&Info,0,
  NULL,37,NULL
};
/*** REQUESTER GADGET ***/
static struct Gadget ReqGad={
  NULL,247,123,100,10,GADGHIMAGE,RELVERIFY|TOGGLESELECT,BOOLGADGET,
  (APTR)&DBorder[1],(APTR)&DBorder[3],&Pause,0,
  NULL,50,NULL
};
/*** OUTPUT GADGET ***/

static UBYTE UNDOBUF[100];
static UBYTE StringBuff[100];
static struct StringInfo StrInfo = {
  StringBuff,UNDOBUF,0,100,0,0,0,0,0,0,0,0,NULL
};
static struct Gadget OutGad={
  NULL,361,125,100,10,GADGHIMAGE,RELVERIFY+STRINGCENTER,STRGADGET,
  (APTR)&TGadBorder,NULL,NULL,NULL,
  (APTR)&StrInfo,51,NULL
};

static struct NewWindow printwin={
  75,30,490,156,3,1,CLOSEWINDOW|GADGETUP|MOUSEBUTTONS,
  WINDOWCLOSE|WINDOWDEPTH|WINDOWDRAG|ACTIVATE|SMART_REFRESH,
  NULL,NULL,"Print v2.01A - Panneau de configuration",
  NULL,NULL,0,0,0,0,WBENCHSCREEN
};

extern APTR AllocFileRequest();
extern void FreeFileRequest(APTR);
extern long RequestFile(APTR);
extern APTR aslBase;

struct FileRequester{
  APTR  rf_Reserved1;
  BYTE  *rf_File,
        *rf_Dir;
  APTR  rf_Reserved2;
  UBYTE rf_Reserved3,
        rf_Reserved4;
  APTR  rf_Reserved5;
  WORD  rf_LeftEdge,
        rf_TopEdge,
        rf_Width,
        rf_Height,
        rf_Reserved6;
  LONG  rf_NumArgs;
  APTR  rf_ArgList;
  APTR  rf_UserData,
        rf_Reserved7,
        rf_Reserved8;
  BYTE  *rf_Pat;
};

extern struct ExecBase         *SysBase;
extern struct IntuitionBase   *IntuitionBase;
extern struct WBStartup        *WBenchMsg;

struct FileRequester* reqptr;
struct TextFont       *font;
struct Preferences    Prefs;
struct FileInfoBlock  *FIBlock;
struct GfxBase        *GfxBase;
struct ArpBase        *ArpBase;
struct DosBase        *DosBase;
struct IconBase       *IconBase;
struct Window         *win=NULL;
struct IntuiMessage   *msg;
struct FileLock       *lock;
struct Task           *PrintTask;

FILE *out;

/**************************************************************************
 * Routine    : ReadFile()                                                *
 * Fonction   : Lecture du fichier et recopie en mémoire.                 *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE : Tout s'est bien passé.                             *
 *              FALSE : Une erreur s'est produite.                        *
 **************************************************************************/

char *ReadFile(){
  struct FileHandle *FH;
  char *Buffer;
  if(!(Buffer=(char *)AllocMem(SIZE,MEMF_CLEAR))) 
    return(0);
  else 
    if(!(FH=(struct FileHandle *)Open(File,MODE_OLDFILE))){
      FreeMem(Buffer,SIZE);
      return(0);
    }
  else 
    if(Read(FH,Buffer,SIZE)!=SIZE){
      FreeMem(Buffer,SIZE);
      Close(FH);
      return(0);
    }
  else{
    Close(FH);
    return(Buffer);
  }
}

/**************************************************************************
 * Routine    : NextPage()                                                *
 * Fonction   : Affiche le requester de pause entre chaque page           *
 *              (uniquement si gadget 'Pause' est activé).                *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : Valeur renvoyée par le requester (TRUE/FALSE).            *
 **************************************************************************/

BOOL NextPage(){
  BOOL reqclear=FALSE,
       rep;
  if(NoReq)
     return(TRUE);
  rep=AutoRequest(IntuitionBase->ActiveWindow,&RText,&RGText[0],&RGText[1],NULL,NULL,320,60);
  switch(rep){
    case TRUE:
      reqclear=2;
      break;
    case FALSE:
      reqclear=1;
      break;
  }
  return((BOOL)(reqclear-1));
}

/**************************************************************************
 * Routine    : PrintPage(r,p,s)                                          *
 * Fonction   : Imprime une page de texte.                                *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : SHORT r : nombre de lignes déjà imprimée.                 * 
 *              ULONG p : position du pointeur dans le fichier.           *
 *              SHORT s : numéro de la page en cours.                     *
 * Sortie     : ULONG p                                                   *
 **************************************************************************/

ULONG PrintPage(SHORT r,ULONG p,SHORT s){
  SHORT i,len,tabs;
  while((r++<ZpS)&&(p<SIZE)){
    LNr++;
    if(SEL(10)){
      len=strlen(TextBuffer[10]);
      for(i=0;i<len;i++){
        if(TextBuffer[10][i]=='#')
          fprintf(out,"%4d ",LNr);
        else
          fprintf (out,"%c",TextBuffer[10][i]);
      }
    }
    do{
      fprintf(out,"%c",FBuffer[p]);
    }while (FBuffer[p++]!='\n');
  }
  if(SEL(9))
    fprintf(out,"\n%s\n",TextBuffer[9]);
  if(SEL(12)){
    for(i=19;i<22;i++)  
      if(SEL(i))
        tabs = (i-19)*4;
    for(i=0;i<tabs;i++) 
      fprintf(out,"\t");
    fprintf(out,"- Page %d -\n",s);
  }
  fprintf(out,"\014"); /* Un saut de page */
  return(p);
}

/**************************************************************************
 * Routine    : _main()                                                   *
 * Fonction   : Programme principal                                       *
 **************************************************************************/

_main(){
  ULONG Class,j=0;
  USHORT Code,id;
  APTR  Address;
  SHORT i,n=0;
  BOOL Quit=FALSE;
  LONG OldDir;
  char **ToolArray;
  char *Value;

  struct DiskObject *DiskLock;
  struct WBArg      *Arg;

  PrintTask=SysBase->ThisTask;

  if(((struct Process *)PrintTask)->pr_CLI){
    PRINT("Print version 2.01A écrit en C par Xavier Mertens (Avr.90 -Sep.92)\n");
    PRINT("Use only from WorkBench 2.x!\n");  
    CloseAll(NULL);
  }

  strcpy(OutPut,"PRT:");

  if(!(IconBase=(struct IconBase *)OpenLibrary("icon.library",OS_VERSION)))
    CloseAll(NO_ICON);

  for(i=0,Arg=WBenchMsg->sm_ArgList;i<WBenchMsg->sm_NumArgs;i++,Arg++){
    OldDir=CurrentDir(Arg->wa_Lock);
    if(DiskLock=GetDiskObject(Arg->wa_Name)){
      ToolArray=DiskLock->do_ToolTypes;
      if(Value=FindToolType(ToolArray,"PAUSE"))
        NoReq=MatchToolValue(Value,"OFF");
      if(Value=FindToolType(ToolArray,"OUTPUT"))
        strcpy(OutPut,Value);
      if(Value=FindToolType(ToolArray,"STYLE")){
        if(MatchToolValue(Value,"NLQ"))
          BGad[13].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"ELITE"))
          BGad[14].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"CONDENSE"))
          BGad[15].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"MINI"))
          BGad[16].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"ITALIQUE"))
          BGad[17].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"GRAS"))
          BGad[18].Flags=GADGHIMAGE|SELECTED;
      }
      if(Value=FindToolType(ToolArray,"ENTETE")){
        if(MatchToolValue(Value,"NOM"))
          BGad[0].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"COMMENTAIRE"))
          BGad[1].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"DATE"))
          BGad[2].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"HEURE"))
          BGad[3].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"OCTETS"))
          BGad[4].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"MOTS")
          BGad[5].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"LIGNES"))
          BGad[6].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"PAGES"))
          BGad[7].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"ENT_LIGNE"))
          BGad[8].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"ENT_PAGE"))
          BGad[9].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"MARGE"))
          BGad[10].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"LIGN_PAGE"))
          BGad[11].Flags=GADGHIMAGE|SELECTED;
        if(MatchToolValue(Value,"NUMERO"))
          BGad[12].Flags=GADGHIMAGE|SELECTED;
      }
      FreeDiskObject(DiskLock);
    }
    CurrentDir(OldDir);
  }
  CloseLibrary(IconBase);  
    
  if(!(aslBase=(APTR)OpenLibrary("asl.library",OS_VERSION)))
    CloseAll(NO_ASL);
  reqptr=(struct FileRequester *)AllocFileRequest();
  if(reqptr){
    if(RequestFile((APTR)reqptr)){
      if(reqptr->rf_Dir[strlen(reqptr->rf_Dir)-1]==':'){
        strcpy(File,reqptr->rf_Dir);
        strcat(File,reqptr->rf_File);
      }
      else{
        strcpy(File,reqptr->rf_Dir);
        strcat(File,"/");
        strcat(File,reqptr->rf_File);
      }
    }
    else{
      CloseLibrary(aslBase);
      CloseAll(NULL);
    }
    FreeFileRequest((APTR)reqptr);
  }
  else{
    CloseLibrary(aslBase);
    CloseAll(NULL);
  }
  CloseLibrary(aslBase);

  OpenAll();

  if(lock=(struct FileLock *)Lock(File,ACCESS_READ)){
    if(FIBlock=(struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock),MEMF_CLEAR)){
      if(!(Examine(lock,FIBlock))){
        UnLock(lock);
        CloseAll(NO_FILE);
      }
    }
    else{
      UnLock(lock);
      CloseAll(NO_MEM);
    }
    UnLock(lock);
  }
  else
    CloseAll(NO_FILE);
  InitBuffers();
  if(!(win=(struct Window *)OpenWindow(&printwin))) 
    CloseAll(NO_WINDOW);
  GetFont();   /* Initialiser Topaz/8 comme fonte système */
  for(i=0;i<BGAD;i++){
    SetBGad(i);
    if(i<TGAD) 
      SetTGad(i);
  }
  AddGadget(win,&PGad,-1);
  RefreshGList(&PGad,win,NULL,1);
  AddGadget(win,&IGad,-1);
  RefreshGList(&IGad,win,NULL,1);
  if(!NoReq)
    ReqGad.Flags=GADGHIMAGE|SELECTED;
  AddGadget(win,&ReqGad,-1);
  RefreshGList(&ReqGad,win,NULL,1);
  strcpy(StringBuff,OutPut);
  AddGadget(win,&OutGad,-1);
  RefreshGList(&OutGad,win,NULL,1);

  SetAPen(RP,1);
  Move(RP,27,150);Draw(RP,27,140);Draw(RP,463,140);
  SetAPen(RP,2);
  Draw(RP,463,150);Draw(RP,27,150);
  GiveHelp("Print v2.01A écrit par Xavier Mertens - Sep.92    ");

  while(!Quit){
    Wait(1<<win->UserPort->mp_SigBit);
    while(msg=(struct IntuiMessage *)GetMsg(win->UserPort)){
      Class    =  msg->Class;
      Code    = msg->Code;
      Address = msg->IAddress;
      id      = ((struct Gadget *)msg->IAddress)->GadgetID;
      switch(Class){
        case CLOSEWINDOW:
          Quit=TRUE;
          break;
        case GADGETUP:
          IPages();
          RefreshGList(&TGad[7],win,NULL,1);
          RefreshGList(&TGad[11],win,NULL,1);
          switch(id){
            case 0:
              GiveHelp("Imprimer le nom de fichier                        ");
              break;
            case 1:
              GiveHelp("Imprimer le commentaire du fichier                ");
              break;
            case 2:
              GiveHelp("Imprimer la date de création du fichier           ");
              break;
            case 3:
              GiveHelp("Imprimer l'heure de création du fichier           "); 
              break;
            case 4:
              GiveHelp("Imprimer la taille du fichier en octets           ");
              break;
            case 5:
              GiveHelp("Imprimer la taille du fichier en mots             ");
              break;
            case 6:
              GiveHelp("Imprimer la taille du fichier en lignes           ");
              break;
            case 7:
              GiveHelp("Imprimer la taille du fichier en pages            ");
              break;
            case 8:
              GiveHelp("Imprimer un entête de ligne                       ");
              break;
            case 9:
              GiveHelp("Imprimer un bas de page                           ");
              break;
            case 10:
              GiveHelp("Insérer une marge  ('#' pour la numérotation)     ");
              break;
            case 11:
              GiveHelp("Fixer le nombre de lignes par pages               ");
              break;
            case 12:
              GiveHelp("Numérotation automatique des pages                ");
              break;
            case 13:
              GiveHelp("Imprimer en mode NLQ                              ");
              break;
            case 14:
              GiveHelp("Imprimer en mode ELITE                            ");
              break;
            case 15:
              GiveHelp("Imprimer en mode CONDENSE                         ");
              break;
            case 16:
              GiveHelp("Imprimer en mode MINI                             ");
              break;
            case 17:
              GiveHelp("Imprimer en mode ITALIQUE                         ");
              break;
            case 18:
              GiveHelp("Imprimer en mode GRAS                             ");
              break;
            case 19:
              GiveHelp("Numérotation des pages à GAUCHE                   ");
            case 20:
              if(id==20)
                GiveHelp("Numérotation des pages au MILIEU                  ");
            case 21:
              if(id=21)
                GiveHelp("Numérotation des pages à DROITE                   ");
              BGad[id].Flags=GADGHIMAGE|SELECTED;
              if(id==19) BGad[20].Flags=BGad[21].Flags=GADGHIMAGE;
              else 
                if(id==20) BGad[19].Flags=BGad[21].Flags=GADGHIMAGE;
              else 
                if(id==21) BGad[19].Flags=BGad[20].Flags=GADGHIMAGE;
              RefreshGList(&BGad[19],win,NULL,3);
              break;
            case 34:  /* C'est parti pour l'impression... */
              GiveHelp("Impression du fichier                             ");
              LNr=0;
              if(!(out=fopen(OutPut,"w"))) 
                CloseAll(NO_OUTPUT);
              if(win){
                CloseWindow(win);
                win=NULL;
              }
              fprintf(out,"%c(B",27); /* SetFr */
              for(i=13;i<19;i++) 
                if(SEL(i)) 
                  fprintf(out,"%c[%s",27,Style[i-13]);
              /* On fixe la priorité à -5 pendant l'impression... */
              SetTaskPri(PrintTask,PRIORITE);
              if (!(NextPage())){
                fprintf(out,"%cc",27);
                fclose(out);
                break;
              }
                /* Impression des données demandées... */
              for(i=0;i<8;i++)
                if(SEL(i)){
                  fprintf(out,"# %s\n",TextBuffer[i]);
                   n++;
                 }
              if(n){
                fprintf(out,"\n\n");
                if(SEL(9))  
                  n+=2;
                if(SEL(12)) 
                  n++;
                j=PrintPage(n+2,0,1);
                if(!(NextPage())){
                  fprintf(out,"%cc",27);
                  fclose(out);
                  break;
                }
              }
              PrintText(j);
              fprintf(out,"%cc",27);
              fclose(out);
              CloseAll(NULL);
              break;
            case 37:
              GiveHelp("Informations sur le programme                     ");
              Warning(INFO);
              break;
            case 50:
              GiveHelp("Insertion d'une pause entre chaque page           ");
              if(ReqGad.Flags=GADGHIMAGE|SELECTED){
                NoReq=0;                    /* Pause entre chaque page */
                strcpy(OutPut,"PRT:");       /* Sortie obligatoire sur PRT: */
                break;
              }
              else{
                NoReq=1;                    /* Pas de pause  */
                break;                  
              }
              break;
            case 51:
              GiveHelp("Modifie la sortie du programme                     ");
              strcpy(OutPut,StringBuff);
              break;
          }
          break;
        default:
          IPages();
          RefreshGList(&TGad[7],win,NULL,1);
          RefreshGList(&TGad[11],win,NULL,1);
          break;
      }
    }
  }
  CloseAll(NULL);
}

/**************************************************************************
 * Routine    : Warning(code)                                             *
 * Fonction   : Affiche un requester avec le message correspondant au code*
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : int code : Numéro du texte à afficher dans le requester   *
 *                          (voir ErrorCodes.h).                          *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

Warning(int code){
  static struct IntuiText Oui={
    0,1,JAM2,5,3,&MyFont,(UBYTE *)"Ok!",NULL
  };
  AutoRequest(IntuitionBase->ActiveWindow,&ErrMsg[code],NULL,&Oui,NULL,NULL,320,60);
  return(TRUE);
}

/**************************************************************************
 * Routine    : CloseAll()                                                *
 * Fonction   : Fermeture de toutes les resources puis quitter.           *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : - (retour au WB)                                          *
 **************************************************************************/

CloseAll(int err){
  if(err)            Warning(err);
  if(FBuffer)       FreeMem(FBuffer,SIZE);
  if(FIBlock)       FreeMem(FIBlock,sizeof(struct FileInfoBlock));
  if(win)           CloseWindow(win);
  if(font)          CloseFont(font);
  if(GfxBase)       CloseLibrary(GfxBase);
  if(IntuitionBase) CloseLibrary(IntuitionBase);
  if(DosBase)        CloseLibrary(DosBase);
  Exit(0);
  return(FALSE);  /* Uniquement pour éviter un Warning durant la  */
                  /* compilation                                   */
}

/**************************************************************************
 * Routine    : OpenAll()                                                 *
 * Fonction   : Ouverture des bibliothèques et lecture des prefs.         *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

OpenAll(){
  if(!(IntuitionBase=(struct IntuitionBase *) OpenLibrary("intuition.library",OS_VERSION))) 
    CloseAll(NO_INTUITION);
  if(!(GfxBase=(struct GfxBase *) OpenLibrary("graphics.library",OS_VERSION))) 
    CloseAll(NO_GRAPHICS);
  if(!(DosBase=(struct DosBase *)OpenLibrary("dos.library",OS_VERSION)))
    CloseAll(NO_DOS);
  GetPrefs(&Prefs,sizeof(struct Preferences));
  return(TRUE);
}

/**************************************************************************
 * Routine    : SetBGad(id)                                               *
 * Fonction   : Affiche les gadgets BOOLEEN dans la fenêtre.              *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : SHORT id : Numéro du gadget en cours.                     *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

SetBGad(SHORT id){
  if(GadgetText[id]){
     IText[id].FrontPen  = 1;
     IText[id].BackPen   = 0;
     IText[id].DrawMode  = JAM1;
     IText[id].LeftEdge  = -100;
     IText[id].TopEdge   = 2;
     IText[id].ITextFont = &MyFont;
     IText[id].IText     = GadgetText[id];
     IText[id].NextText  = NULL;
  }
  BGad[id].NextGadget    = NULL;
  BGad[id].LeftEdge      = xb[id]+100;
  BGad[id].TopEdge       = yb[id];
  BGad[id].Width         = 20;
  BGad[id].Height        = 10;
  if(id==19)
    BGad[id].Flags       = GADGHIMAGE|SELECTED;
  else
    BGad[id].Flags       |= GADGHIMAGE;
  BGad[id].Activation    = TOGGLESELECT|RELVERIFY;
  BGad[id].GadgetType    = BOOLGADGET;
  BGad[id].GadgetRender  = (APTR)&BGadBorder[1];
  BGad[id].SelectRender  = (APTR)&BGadBorder[3];
  BGad[id].GadgetText    = GadgetText[id]?&IText[id]:NULL;
  BGad[id].MutualExclude = 0;
  BGad[id].SpecialInfo   = NULL;
  BGad[id].GadgetID      = id;
  BGad[id].UserData      = NULL;
  AddGadget(win,&BGad[id],-1);
  RefreshGList(&BGad[id],win,NULL,1);
  return(TRUE);
}

/**************************************************************************
 * Routine    : SetTGad(id)                                               *
 * Fonction   : Affiche les gadgets STRING dans la fenêtre.               *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : SHORT id : Numéro du gadget en cours.                     *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

SetTGad(SHORT id){
  SInfo[id].Buffer       = TextBuffer[id];
  SInfo[id].UndoBuffer   = UndoBuffer;
  SInfo[id].MaxChars     = 200;
  SInfo[id].BufferPos    = SInfo[id].LongInt   = 0;
  SInfo[id].DispPos      = SInfo[id].UndoPos   = 0;
  SInfo[id].NumChars     = SInfo[id].DispCount = 0;
  SInfo[id].CLeft        = SInfo[id].CTop      = 0;
  SInfo[id].LayerPtr     = SInfo[id].AltKeyMap = NULL;
  TGad[id].NextGadget    = NULL;
  TGad[id].LeftEdge      = xt[id];
  TGad[id].TopEdge       = yb[id]+2;
  TGad[id].Width         = 100;
  TGad[id].Height        = 10;
  TGad[id].Flags         = GADGHCOMP;
  TGad[id].Activation    = RELVERIFY;
  TGad[id].GadgetType    = STRGADGET;
  TGad[id].GadgetRender  = (APTR)&TGadBorder;
  TGad[id].SelectRender  = NULL;
  TGad[id].GadgetText    = NULL;
  TGad[id].MutualExclude = 0;
  TGad[id].SpecialInfo   = (APTR)&SInfo[id];
  TGad[id].GadgetID      = id+BGAD;
  TGad[id].UserData      = NULL;
  AddGadget(win,&TGad[id],-1);
  RefreshGList(&TGad[id],win,NULL,1);
  return(TRUE);
}

/**************************************************************************
 * Routine    : IDate()                                                   *
 * Fonction   : Calcule la date de création du fichier.                   *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

IDate(){
  SHORT JTage,j,m,n,t=DATE->ds_Days;
  n=t%7;
  for(j=1978;;j++){
    JTage=(j%4==0)?366:365;
    if(t<JTage) 
      break;
    else 
      t-=JTage;
  }
  MTage[1]=JTage-337;
  for(m=0;t>MTage[m];m++) t-=MTage[m];
  sprintf(TextBuffer[2],"%s,%d %s %d",Jour[n+1],t+1,Mois[m],j);
  return(TRUE);
}

/**************************************************************************
 * Routine    : ITime()                                                   *
 * Fonction   : Calcule l'heure de création du fichier.                   *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

ITime(){
  SHORT h,m,s;
  h=DATE->ds_Minute/60;
  m=DATE->ds_Minute%60;
  s=(DATE->ds_Tick/50)%60;
  sprintf(TextBuffer[3],"%d:%d:%d",h,m,s);
  return(TRUE);
}

/**************************************************************************
 * Routine    : ISize()                                                   *
 * Fonction   : Calcule le nombre de mots et de lignes du texte.          *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

ISize(){
  SHORT w=0,l=0;
  ULONG i;
  if(!(FBuffer=ReadFile())) CloseAll(NO_FILE);
  TabToSpace(FBuffer);
  for(i=0,ZGes=0;i<SIZE;i++){
    for(;FBuffer[i]!='\n';i++){
      if((FBuffer[i]==' ')||(FBuffer[i]=='\t')){
        if(l){
          do{ 
            i++;
          }while((FBuffer[i]==' ')||(FBuffer[i]=='\t'));
          i--;
          w++;
          l=0;
        }
      }
      else{
        l=1;
        if(FBuffer[i]==' ')
          FBuffer[i]=27;
      }
    }
    if(l){
      w++;
      l=0;
    }
    ZGes++;
  }
  sprintf(TextBuffer[5],"%d Mots",w);
  sprintf(TextBuffer[6],"%d Lignes",ZGes);
  return(TRUE);
}

/**************************************************************************
 * Routine    : IPages()                                                  *
 * Fonction   : Calcule le nombre de pages du texte.                      *
 * Version    : 1.00                                                      *
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Opération réalisée avec succès.                   *
 **************************************************************************/

IPages(){
  USHORT i,n,p,zg,zs,z=0;
  for(i=0,n=0;i<8;i++) 
    if(SEL(i)) 
      n++;
  if(n) 
    n+=2;
  zg=ZGes+n;
  if (SEL(11)&&atoi(TextBuffer[11])<15){
    DisplayBeep(NULL);
    sprintf(TextBuffer[11],"%d",PLEN>15?PLEN:65);
  }
  ZpS=SEL(11)?atoi(TextBuffer[11]):PLEN;
  if(SEL(8))
    z+=2;
  if(SEL(9))  
    z+=2;
  if(SEL(12)) 
    z++;
  zs=ZpS-z;
  p=zg%zs?zg/zs+1:zg/zs;
  sprintf(TextBuffer[7],"%d Page(s)",p);
  return(TRUE);
}

/**************************************************************************
 * Routine    : InitBuffers()                                             *
 * Fonction   : Initialise les variables relatives au fichier (nom,...)   *
 * Version    : 1.00                                                      *  
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Pas de problème.                                  *
 **************************************************************************/

InitBuffers(){
  sprintf(TextBuffer[0],"%s",NAME);
  sprintf(TextBuffer[1],"%s",COMM);
  IDate();
  ITime();
  sprintf(TextBuffer[4],"%d Bytes",SIZE);
  ISize();
  IPages();
  sprintf(TextBuffer[10],"\t");
  sprintf(TextBuffer[11],"%d",ZpS);
  return(TRUE);
}

/**************************************************************************
 * Routine    : PrintText(pos)                                            *
 * Fonction   : Imprime le texte présent en mémoire.                      *
 * Version    : 1.00                                                      *  
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : ULONG pos : position dans le texte.                       *                                                          *
 * Sortie     : TRUE  : Impression réalisée avec succès.                  *
 **************************************************************************/

PrintText(ULONG pos){
  SHORT pages,n=0;
  if(SEL(8))  
    n+=2;
  if(SEL(9))  
    n+=2;
  if(SEL(12)) 
    n++;
  for(pages=pos?2:1;pos<SIZE;pages++){
    if(SEL(8)) 
      fprintf(out,"%s\n\n",TextBuffer[8]);
    pos=PrintPage(n,pos,pages);
    if(pos<SIZE) 
      if(!NextPage()) 
        return(TRUE);
  }
  AutoRequest(IntuitionBase->ActiveWindow,&EndText,NULL,&RGText[0],NULL,NULL,320,60);
  return(TRUE);
}

/**************************************************************************
 * Routine    : GetFont()                                                 *
 * Fonction   : Initialise la fonte Topaz.8 pour tout le programme.       *
 * Version    : 1.00                                                      *  
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Installation réalisée avec succès.                *
 **************************************************************************/

GetFont(){
  MyFont.ta_Name  = FONT;
  MyFont.ta_YSize = 8;
  MyFont.ta_Style = 0;
  MyFont.ta_Flags = 0;
  if(font=(struct TextFont *)OpenFont(&MyFont)){
    SetFont(win->RPort, font);
    return(TRUE);
  }
  else
    CloseAll(NO_FONT);
  return(FALSE);
}

/**************************************************************************
 * Routine    : TabToSpace()                                              *
 * Fonction   : Convertit les tabulations (0x09) en espace (0x20).        *
 * Version    : 1.00                                                      *  
 * Date       : 07 Sep 1992 - 10:30                                       *
 * Paramètres : -                                                         *
 * Sortie     : TRUE  : Convertion terminée.                              *
 **************************************************************************/

TabToSpace(char *Buffer){
  int j=0;
  for(j=0;j<SIZE;j++)
    if(Buffer[j]=='\t')
      Buffer[j]=' ';
  return(TRUE);
}

/**************************************************************************
 * Routine    : GiveHelp(message)                                         *
 * Fonction   : Affiche la ligne de texte donnée dans l'espace réservé    *
 *              (en bas du panneau de configuration).                     *
 * Version    : 1.00                                                      *  
 * Date       : 08 Sep 1992 - 11:08                                       *
 * Paramètres : char *message : le texte à afficher (max 50 car.)         *
 * Sortie     : TRUE                                                      *
 **************************************************************************/

GiveHelp(char *message){
  SetAPen(RP,1);
  Move(RP,32,148);
  Text(RP,message,strlen(message));
  return(TRUE);
}

/* Eof */

