/***************************************************************************
 *
 *  
 *      ShowDoc    --   C_DICE_SOURCE  -- 
 *
 *      © 1992  LECLERCQ XAVIER 
 *
 *      Version 1.0     
 *
 ***************************************************************************/

/***************************************************************************/
/*
 * #include
*/ 
#include <stdio.h>
#include <libraries/dosextens.h>
#include <graphics/gfxmacros.h>
#include <exec/execbase.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/screens.h>
#include <graphics/gfxbase.h>
#include <devices/printer.h>
#include <devices/prtgfx.h>
#include <devices/timer.h>
#include <exec/memory.h>
#include <ctype.h>
#include "lhlib.h"
#include "libraries/reqtools.h"
#include "libraries/minrexx.h"
#include "libraries/arexx.h"

/***************************************************************************
 *
 * #define
*/
#define BOX_LOAD_X1   147
#define BOX_LOAD_X2   217
#define BOX_LOAD_Y1   255-228
#define BOX_LOAD_Y2   255-240
#define BOX_SAVE_X1   147
#define BOX_SAVE_X2   217
#define BOX_SAVE_Y1   255-211
#define BOX_SAVE_Y2   255-223
#define BOX_QUIT_X1   572
#define BOX_QUIT_X2   618
#define BOX_QUIT_Y1   255-219
#define BOX_QUIT_Y2   255-231
#define BOX_LINEUP_X1 298
#define BOX_LINEUP_X2 368
#define BOX_LINEUP_Y1 255-228
#define BOX_LINEUP_Y2 255-240
#define BOX_LINEDO_X1 299
#define BOX_LINEDO_X2 369
#define BOX_LINEDO_Y1 255-211
#define BOX_LINEDO_Y2 255-223
#define BOX_PAGEUP_X1 222
#define BOX_PAGEUP_X2 292
#define BOX_PAGEUP_Y1 255-228
#define BOX_PAGEUP_Y2 255-240
#define BOX_PAGEDO_X1 222
#define BOX_PAGEDO_X2 292
#define BOX_PAGEDO_Y1 255-211
#define BOX_PAGEDO_Y2 255-223
#define BOX_PRINT_X1  375
#define BOX_PRINT_X2  445
#define BOX_PRINT_Y1  255-211
#define BOX_PRINT_Y2  255-223
#define BOX_ABOUT_X1  374
#define BOX_ABOUT_X2  444
#define BOX_ABOUT_Y1  255-228
#define BOX_ABOUT_Y2  255-240
#define MSG_ERR_1     "ERR 01 : You need 'libs:reqtools.library' !!"
#define MSG_ERR_2     "ERR 02 : intuition.library open error!"
#define MSG_ERR_3     "ERR 03 : graphics.library open error!"
#define MSG_ERR_4     "ERR 04 : lh.library open error!"
#define MSG_ERR_5     "ERR 05 : Out of memory to decode!"
#define MSG_ERR_6     "ERR 06 : Screen open error!"
#define MSG_ERR_7     "ERR 07 : Window open error!"
#define MSG_ERR_8     "ERR 08 : Out of memory to load file!"
#define MSG_ERR_9     "ERR 09 : File open error!"
#define MSG_ERR_10    "ERR 10 : File read Error(s) !!"
#define MSG_ERR_11    "ERR 11 : Out of memory for crunching... !!"
#define MSG_ERR_12    "ERR 12 : Crunching size > uncrunching size !!"
#define MSG_ERR_13    "ERR 13 : File write Error(s) !!"
#define MSG_ERR_14    "ERR 14 : Out of memory to save file!"
#define MSG_ERR_15    "ERR 15 : Printer trouble !"
#define MSG_ERR_16    "ERR 16 : ARexx trouble !"
#define MSG_WARN      "WARNING..."
#define MSG_EXIT      "Are you sure ?"
#define MSG_ERROR     "Error!"
#define MSG_OUIN      "YES|NO"
#define MSG_QUIT      "QUIT.."
#define MSG_EXIT      "Are you sure ?"
#define MSG_OK        "OK"
#define MSG_LOAD      "Load new File"
#define MSG_SAVE      "Save new File"
#define MSG_CHOIX     "ASCII|CRUNCHING"
#define MSG_CH        "Choose save file method..."
#define TITLE_SAVE    "Save file"
#define TITLE_QUITTER "Quit..."
#define ARexxPortNom  "ShowDoc"
#define NBR_COLORS    16L
#define FromSize      2648L        
#define ToSize1       3924L
#define ToSize2       81952L
#define TITLE_ABOUT   "About.."
#define MSG_ABOUT   \
"ShowDoc version 1.0\n"\
"===================\n\n"\
"La première publication de ShowDoc est \n"\
"réservée pour Le Petit Amiga illustré. Et après quelques mois\n"\
"ShowDoc deviendra un domaine public en SHAREWARE.\n"\
"Auteur : LECLERCQ XAVIER\n"\
"Vieux Chemin d'Ath n°12 B-7548 Warchin BELGIUM\n\n"\
"ARexx Port : ShowDoc\n"\
"°°°°°°°°°°°°°°°°°°°°"
static char *VERSION = " $VER: ShowDoc 1.0 (31.07.92)";
/***************************************************************************
 * 
 * variables globales
*/
struct ReqToolsBase     *ReqToolsBase  = NULL;
struct Library		*LhBase        = NULL;
struct LhBuffer		*LhBuffer      = NULL;
struct IntuitionBase    *IntuitionBase = NULL;
struct GfxBase          *GfxBase       = NULL;
struct ViewPort         *viewport      = NULL;
struct RastPort         *rastport      = NULL;
struct Screen           *ecran         = NULL;
struct Window           *fenetre       = NULL;
struct IntuiMessage     *message       = NULL;
struct Image image;
ULONG  classemessage =  NULL ,nbligne = 0;
ULONG  *From  = NULL;
ULONG  *To1   = NULL;
ULONG  *To2   = NULL;
ULONG  *pfp   = NULL;
BPTR In,Out;
APTR BuffCouleurs = NULL;
USHORT xmouse , ymouse;
ULONG  lfp = 0L;
char   *psl = NULL , *pfin = NULL , *Dest = NULL;
ULONG  *pl = NULL;
BOOL  FlagDown , FlagLoad = FALSE , MarqueDecomp = FALSE;
BOOL  ARexxFlag = FALSE , FlagArg = FALSE , FlagComp = TRUE;
char olddir[512] , filename[134];
/***************************************************************************/
WR(char *str) { Write(Output(), str ,strlen(str)); }
/***************************************************************************/
MsgErr(char *str) {  
 rtEZRequestTags (str,MSG_QUIT,NULL,NULL,
                  RT_ReqPos , REQPOS_CENTERWIN ,
                  RTEZ_ReqTitle , MSG_ERROR ,
                  TAG_END), FermeAll(); }
/***************************************************************************/
PutErr(char *str) {
   (FlagComp)?rtEZRequestTags (str,MSG_QUIT,NULL,NULL,
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERSCR ,
                  RTEZ_Flags , EZREQF_CENTERTEXT ,
                  RTEZ_ReqTitle , MSG_ERROR ,
                  TAG_END)
             :MsgErr(str),FermeAll(); 
}
/***************************************************************************/
PutWarn(char *str) {
   rtEZRequestTags (str,MSG_QUIT,NULL,NULL,
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERSCR ,
                  RTEZ_Flags , EZREQF_CENTERTEXT ,
                  RTEZ_ReqTitle , MSG_WARN ,
                  TAG_END); }
/****************************************************************************/
OuvreAll()
{
 ReqToolsBase = (struct ReqToolsBase *) OpenLibrary("reqtools.library",0L);
 if (!ReqToolsBase) WR(MSG_ERR_1"\n\n"),FermeAll();

 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library",0L);
 if (!IntuitionBase) MsgErr(MSG_ERR_2);

 GfxBase = (struct GfxBase *) OpenLibrary("graphics.library",0L);
 if (!GfxBase) MsgErr(MSG_ERR_3);

 LhBase = (struct Library *)OpenLibrary(LH_NAME,LH_VERSION);
 if (!LhBase) MsgErr(MSG_ERR_4);

 LhBuffer = (struct LhBuffer *)CreateBuffer(FALSE);
 if (!LhBuffer) MsgErr(MSG_ERR_5);


 UnPackShowDocIFF();

 if (FlagComp) {
   OuvreEcran();
   OuvreFen();
   DisplayOff();
   AfficheEcran();
   DisplayOn();
 }
}
/****************************************************************************/
FermeAll()
{
 if (ReqToolsBase ) CloseLibrary ((struct ReqToolsBase  *) ReqToolsBase );
 if (IntuitionBase) CloseLibrary ((struct IntuitionBase *) IntuitionBase);
 if (GfxBase)       CloseLibrary ((struct GfxBase       *) GfxBase      );
 if (LhBase )       CloseLibrary ((struct Library       *) LhBase       );
 if (LhBuffer)      DeleteBuffer(LhBuffer);
 if (To2)           FreeMem(To2,ToSize2);
 if (fenetre)       FermeFen();
 if (ecran)         FermeEcran();
 if (pl)            FreeMem(pl,lfp);
 if (pfp)           FreeMem(pfp,lfp);
 if (ARexxFlag)     dnRexxPort();
 exit(0);
}
/****************************************************************************/
UnPackShowDocIFF()
{
 if (!(From = (ULONG *)AllocMem(FromSize,MEMF_PUBLIC | MEMF_CLEAR))) {
   MsgErr(MSG_ERR_5);
 }

 if (!(To1 = (ULONG *)AllocMem(ToSize1,MEMF_PUBLIC | MEMF_CLEAR))) {
   FreeMem(From,FromSize);
   MsgErr(MSG_ERR_5);
 }
 extern ShowDocIFF;

 APTR ptr = &ShowDocIFF;

 memcpy ( From , ptr , FromSize);
 
 LhBuffer -> lh_Src = From;
 LhBuffer -> lh_Dst = To1;

 LhDecode(LhBuffer);
 
 if (!(To2 = (ULONG *)AllocMem(ToSize2,MEMF_CHIP | MEMF_CLEAR))) {
   FreeMem(From,FromSize);
   FreeMem(To1,ToSize1);
   MsgErr(MSG_ERR_5);
 }

 LhBuffer -> lh_Src = To1;
 LhBuffer -> lh_Dst = To2;

 LhDecode(LhBuffer);
 
 FreeMem(From,FromSize);
 FreeMem(To1,ToSize1);
}
/***************************************************************************/
int PackTxt()
{
  if(!(Dest = (LONG *)AllocMem(lfp + ENCODEEXTRA(lfp)
       ,MEMF_PUBLIC|MEMF_CLEAR))) {
    PutErr(MSG_ERR_11);
    return(1);
  }
  LhBuffer -> lh_Src     = pfp;
  LhBuffer -> lh_SrcSize = lfp;
  LhBuffer -> lh_Dst     = Dest;
  DisplayOff();
  LhEncode(LhBuffer);
  DisplayOn();
  if (LhBuffer -> lh_DstSize >= lfp ) {
    PutErr(MSG_ERR_12);
    return(2);
  }
  else
    return(0);
}
/***************************************************************************/
OuvreEcran()
{
 struct NewScreen necr;

 necr.LeftEdge     = 0;
 necr.TopEdge      = 0;
 necr.Width        = 640;
 necr.Height       = 256;
 necr.Depth        = 4;
 necr.DetailPen    = 8;
 necr.BlockPen     = 8;
 necr.ViewModes    = HIRES;
 necr.Type         = CUSTOMSCREEN;
 necr.Font         = NULL;
 necr.DefaultTitle = NULL;
 necr.Gadgets      = NULL;
 necr.CustomBitMap = NULL;
 ecran = (struct Screen *) OpenScreen(&necr);
 if(!ecran) MsgErr(MSG_ERR_6);
}
/***************************************************************************/
FermeEcran()
{
 if (ecran) CloseScreen(ecran);
}
/***************************************************************************/
OuvreFen()
{
 struct NewWindow nfen;
 nfen.LeftEdge     = 0;
 nfen.TopEdge      = 0;
 nfen.Width        = 640;
 nfen.Height       = 256;
 nfen.DetailPen    = 8;
 nfen.BlockPen     = 8;
 nfen.IDCMPFlags   = MOUSEBUTTONS|RAWKEY;
 nfen.Flags        = WINDOWDRAG|ACTIVATE|BACKDROP|
                     BORDERLESS|NOCAREREFRESH;
 nfen.FirstGadget  = NULL;
 nfen.CheckMark    = NULL;
 nfen.Title        = NULL;
 nfen.Screen       = ecran;
 nfen.BitMap       = NULL;
 nfen.MinWidth     = 640;
 nfen.MinHeight    = 256;
 nfen.MaxWidth     = 640;
 nfen.MaxHeight    = 256;
 nfen.Type         = CUSTOMSCREEN;
 fenetre = (struct Window *)OpenWindow(&nfen);
 if (!fenetre) MsgErr(MSG_ERR_7);
}
/***************************************************************************/
FermeFen()
{
 if (fenetre) CloseWindow(fenetre);
}
/***************************************************************************/
AfficheEcran()
{
 rastport = fenetre->RPort;
 image.LeftEdge   = 0;
 image.TopEdge    = 0;
 image.Width      = 640;
 image.Height     = 256;
 image.Depth      = 4;
 image.ImageData  = To2;
 image.PlanePick  = 15;
 image.PlaneOnOff = 0;
 image.NextImage  = NULL;
 DrawImage(rastport,&image,0L,0L); 
}
/***************************************************************************/
DisplayOff()
{
 if (!(FlagComp)) return(0);
 UWORD BlackCols[16];
 SHORT i;
 for (i=0;i<16;BlackCols[i++]=0);
 viewport = (struct ViewPort *)ViewPortAddress(fenetre);
 LoadRGB4 (viewport,BlackCols,NBR_COLORS); 
}
/***************************************************************************/
DisplayOn()
{ 
 if (!(FlagComp)) return(0);
 ULONG *ptr;
 ptr = To2;
 ptr += 20480;
 viewport = (struct ViewPort *)ViewPortAddress(fenetre);
 LoadRGB4 (viewport,ptr,NBR_COLORS); 
 ScreenToFront(ecran);
}
/***************************************************************************/
About()
{
rtSetWaitPointer(fenetre);
rtEZRequestTags (MSG_ABOUT , MSG_OK , NULL , NULL ,  
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERSCR ,
                  RTEZ_ReqTitle , TITLE_ABOUT , 
                  RTEZ_Flags , EZREQF_CENTERTEXT ,
                  TAG_END );
}
/***************************************************************************/
Quitter()
{
 rtSetWaitPointer(fenetre);
 switch (rtEZRequestTags (MSG_EXIT,MSG_OUIN,NULL,NULL,
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERWIN ,
                  RTEZ_ReqTitle , TITLE_QUITTER,
                  TAG_END)) {
 case TRUE: 
   DisplayOff();
   FermeAll();
 }
}
/***************************************************************************/
Save()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }
 struct rtFileRequester *filereq = NULL;
 char filename[134];
 FILE *fp = NULL;
 int re;
 ULONG cf = 0;
 
 getcwd(olddir,sizeof(olddir));    
 switch (rtEZRequestTags (MSG_CH,MSG_CHOIX,NULL,NULL,
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERWIN ,
                  RTEZ_ReqTitle , TITLE_SAVE,
                  TAG_END)) {
 case TRUE: 
 {
     if (filereq = (struct rtFileRequester *)
                   rtAllocRequestA(RT_FILEREQ, NULL)) {
       filename[0] = 0;
       if (rtFileRequest (filereq, filename, MSG_SAVE, 
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERWIN ,
                  TAG_END)) {
         chdir(filereq->Dir);
         if (fp = fopen(filename , "wb")) {
           cf = fwrite(pfp,1,lfp,fp);
           fclose(fp);
           if (cf != lfp)
             PutErr(MSG_ERR_13);
         }
         else
           PutErr(MSG_ERR_9);
       }
     } 
     else
       PutErr(MSG_ERR_14);
 break;
 }
 case FALSE:
 {
   re = PackTxt();
   if (re == 2) {
     FreeMem(Dest,lfp + ENCODEEXTRA(lfp));
   } 
   else {
     if (re == 1) return(0);
     else {
       if (filereq = (struct rtFileRequester *)
                     rtAllocRequestA(RT_FILEREQ, NULL)) {
         filename[0] = 0;
         if (rtFileRequest (filereq, filename, MSG_SAVE, 
                    RT_Window , (struct Window*) fenetre,
                    RT_WaitPointer , TRUE ,
                    RT_ReqPos , REQPOS_CENTERWIN ,
                    TAG_END)) {
           chdir(filereq->Dir);
           if (fp = fopen(filename , "wb")) {
             char *Marque = "SHOWDOC.LH";
             cf = fwrite(Marque,1,strlen(Marque),fp);
             cf = fwrite(&lfp,1,sizeof(lfp),fp);
             cf = fwrite(Dest,1,LhBuffer -> lh_DstSize,fp);
             fclose(fp);
             if (cf != LhBuffer -> lh_DstSize)
               PutErr(MSG_ERR_13);
           }
           else
             PutErr(MSG_ERR_9);
         }
       } 
       else
         PutErr(MSG_ERR_14);
     } 
   FreeMem(Dest,lfp + ENCODEEXTRA(lfp));
   }
 }
 }
 chdir(olddir);
}
/***************************************************************************/
Load()
{
 struct rtFileRequester *filereq = NULL;
 FILE *fp = NULL;
 int i;
 BOOL FlagDecomp;
 ULONG lfp2;
 
 if (FlagComp) AfficheEcran();
 FlagLoad = FALSE;
 if (!(FlagArg))
   for(i=0;i<134;filename[i++]=0x00);
 fp = 0L, lfp = 0L , pl = 0L;
 if (pl)  FreeMem(pl,lfp ),pl  = 0L;
 if (pfp) FreeMem(pfp,lfp),pfp = 0L;
 if (filereq = (struct rtFileRequester *)rtAllocRequestA(RT_FILEREQ, NULL)) {
   getcwd(olddir,sizeof(olddir));
   if ((FlagArg)?1:rtFileRequest (filereq, filename, MSG_LOAD, 
                  RT_Window , (struct Window*) fenetre,
                  RT_WaitPointer , TRUE ,
                  RT_ReqPos , REQPOS_CENTERWIN ,
                  TAG_END)) {
     chdir(filereq->Dir);
     if (fp = fopen(filename , "rb")) {
       rewind(fp);
       char *MarqueCmp[10];
       char *Marque = "SHOWDOC.LH";
       fread(MarqueCmp,1,10,fp);
       FlagDecomp = FALSE;
       if (strcmp(MarqueCmp,Marque) == 0) {
         FlagDecomp = TRUE;
         MarqueDecomp = TRUE;
         fread(&lfp,1,sizeof(lfp),fp);
         int pos;
         pos = ftell (fp);
         fseek (fp,0,SEEK_END);
         lfp2 = ftell (fp);
         lfp2 -= 14;
         fseek (fp,pos,SEEK_SET);
       }  
       else {
         rewind(fp);
         fseek (fp,0,SEEK_END);
         lfp = ftell (fp);
         fseek (fp,0,SEEK_SET);
       }
       if (pfp = (ULONG *)AllocMem(lfp,MEMF_PUBLIC | MEMF_CLEAR)) {
         if (pl = (ULONG *)AllocMem(lfp,MEMF_PUBLIC | MEMF_CLEAR)) {
           ULONG cfp;
           cfp = fread(pfp,1,lfp,fp);
           if (FlagDecomp) {
             if (Dest = (ULONG *)AllocMem(lfp2,MEMF_PUBLIC | MEMF_CLEAR)) {
               memcpy(Dest,pfp,lfp2);
               LhBuffer -> lh_Src = Dest;
               LhBuffer -> lh_Dst = pfp;
               DisplayOff();
               LhDecode(LhBuffer);
               if (FlagComp) DisplayOn();
               FreeMem(Dest,lfp2);
               cfp = LhBuffer -> lh_DstSize;
             }    
             else {
               PutErr(MSG_ERR_8);
               FreeMem(pfp,lfp),pfp = 0L;
               fclose(fp);
               return(0);
             } 
           } 
           if (cfp == lfp) {
             psl = pfp;
             pfin = (char *)pfp;
             pfin += lfp;
             FlagLoad = TRUE;
             nbligne = 0;
             if (FlagComp)
               PageDown();
             fclose(fp);
           }
           else {
             PutErr(MSG_ERR_10);
             fclose(fp);
             FreeMem(pfp,lfp),pfp = 0L;
           }
         }
         else {
           PutErr(MSG_ERR_8);
           fclose(fp);
           FreeMem(pfp,lfp),pfp = 0L;
         }
       }
       else
         fclose(fp);
     }
     else
       PutErr(MSG_ERR_9);
   }
 chdir(olddir);
 }
 else
   PutErr(MSG_ERR_8);
}
/***************************************************************************/
PageDown()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }
 int j;
 SetAPen(rastport, 1L);
 SetBPen(rastport, 9L);
 for(j=0;j<24;j++) {
  AfficheLigneDo();
 } 
}
/***************************************************************************/
PageUp()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }
 int j;
 SetAPen(rastport, 1L);
 SetBPen(rastport, 9L);
 for(j=0;j<24;j++) {
  AfficheLigneUp();
 } 
}
/***************************************************************************/
AfficheLigne(int n)
{
 long arg[1];
 char Buff[10];
 arg[0]=(long) n;
 Convertir(Buff,"%08ld",arg);
 Affiche (490,24,Buff,8);
 n /= 25;
 n++;
 arg[0]=(long) n;
 Convertir(Buff,"%08ld",arg);
 Affiche (490,41,Buff,8);
}
/***************************************************************************/
AfficheLigneDo()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }
 if (psl >= pfin ) {
   DisplayBeep(0L);
   return(0);
 } 
 int i=0,j=0;
 char Ligne[128];
 nbligne++;
 pl[nbligne]=psl;
 for(i=0;i<77;) {
   if (*psl==0x0a ) break;
   if (*psl==0x09 )
     for(j=i+6;i<j;Ligne[i++]=0x20);
   else
     Ligne[i++] = *psl;
   if (psl++ >= pfin) break;
 }  
 if (i >= 77) psl--;
 if (psl >= pfin) {
   DisplayBeep(0L);
   return(0);
 } 
 else { 
   ScrollRaster(rastport,0,8,10,256-198,630,256-7);
   Affiche (10,248,Ligne,i),psl++;
   AfficheLigne(nbligne);
 }
}
/***************************************************************************/
AfficheLigneUp()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }
 if ((nbligne-24) <= 0) {
   DisplayBeep(0L);
   return(0);
 }
 int i,j;
 char Ligne[128];
 psl=(char *)pl[nbligne-24];
 for(i=0;i<77;psl++) {
   if (*psl==0x0a ) break;
   if (*psl==0x09 ) for(j=0;j<6;Ligne[i++]=0x20,j++);
   else Ligne[i++] = *psl;
 }  
 if (i >= 77) psl--;
 ScrollRaster(rastport,0,-8,10,256-198,630,256-7);
 Affiche (10,64,Ligne,i),psl++;
 psl=(char *)pl[nbligne--];
 AfficheLigne(nbligne);
}
/***************************************************************************/
Affiche(LONG x,LONG y,char *Msg,int i)
{
 Move(rastport, x , y);
 Text(rastport, Msg , i);
}
/***************************************************************************/
Imprime()
{
 if (!(FlagLoad)) {
   DisplayBeep(0L);
   return(0);
 }

 FILE *stdprn = NULL;

 if(ferror(stdprn=fopen("PRT:","wb"))) {
     PutWarn(MSG_ERR_15);
     return(0);
   } 

 DisplayOff();
 int i=0,j=0,save;
 char Ligne[81];
 char NL = 0x0a;
 save    = nbligne;
 nbligne = 0;
 char *psl2 = psl;
 psl     = pfp;
 fputc(NL,stdprn);

 while(TRUE) {
   for(i=0;i<77 && *psl!=0x0a && psl < pfin;psl++) {
     if (*psl==0x09 ) for(;j<6;Ligne[i++]=0x20,j++);
     else Ligne[i++] = *psl;
   }  
   if (i >= 77) psl--;
   for(;i<77;Ligne[i++]=' ');
   if (psl >= pfin) {
     nbligne = save;
     fputc(NL,stdprn);
     fclose(stdprn);
     DisplayOn();
     psl = psl2; 
     return(0);
   } 
   else {
     i++;
     Ligne[i++]=0x0a;
     Ligne[i]=0x00;
     fputs(Ligne,stdprn);
     psl++;
   }
 }
}
/***************************************************************************
 *
 * Variables pour ARexx
*/
int rQuitter() , rAbout() , rVersion() , rDisplayOn() , rDisplayOff();
int rImprime() , rAfficheLigneDo() , rAfficheLigneUp() , rPageDown();
int rPageUp() , rLoad() , rSave() , rScrBack() , rScrFront();
static BOOL FlagAbort = FALSE;
struct rexxCommandList CommandList[] =
{
   { "SD_Quit" , (APTR)&rQuitter },
   { "SD_About", (APTR)&rAbout },
   { "SD_Version", (APTR)&rVersion },
   { "SD_ScrON", (APTR)&rDisplayOn },
   { "SD_ScrOFF", (APTR)&rDisplayOff },
   { "SD_Print", (APTR)&rImprime },
   { "SD_LineD", (APTR)&rAfficheLigneDo },
   { "SD_LineU", (APTR)&rAfficheLigneUp },
   { "SD_PageD", (APTR)&rPageDown },
   { "SD_PageU", (APTR)&rPageUp },
   { "SD_Load", (APTR)&rLoad },
   { "SD_Save", (APTR)&rSave },
   { "SD_ScrBack", (APTR)&rScrBack },
   { "SD_ScrFront", (APTR)&rScrFront },
   { NULL, NULL }
};
struct RexxMsg *rexxMsg;
char   arexxBuf[140],*result="RESULT";
UBYTE  errorNum=0;
long   arexxSigBit;
/***************************************************************************/
int ARexxCode(struct RexxMsg *msg,struct rexxCommandList *dat,char *p)
{
  rexxMsg=msg;
  ((int (*)())(dat->userdata))(p);
  replyRexxCmd(rexxMsg,errorNum,0,arexxBuf);
  errorNum=0;
  return(1);
}
/***************************************************************************
 *  Ouvre le Port ARexx                                                    */
long initRexxPort(void)
{
  return(upRexxPort(ARexxPortNom,CommandList,"rx",(APTR)&ARexxCode));
}
/***************************************************************************/
rQuitter()
{
 FlagAbort = TRUE;
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rAbout()
{
 About();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rVersion()
{
 strcpy(arexxBuf,&VERSION[7]);
}
/***************************************************************************/
rPageDown()
{
 PageDown();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rPageUp()
{
 PageUp();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rAfficheLigneDo()
{
 AfficheLigneDo();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rAfficheLigneUp()
{
 AfficheLigneUp();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rLoad()
{
 Load();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rSave()
{
 Save();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rDisplayOn()
{
 DisplayOn();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rDisplayOff()
{
 DisplayOff();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rImprime()
{
 Imprime();
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rScrBack()
{
 ScreenToBack(ecran);
 strcpy(arexxBuf,result);
}
/***************************************************************************/
rScrFront()
{
 ScreenToFront(ecran);
 strcpy(arexxBuf,result);
}
/****************************************************************************
 * Fonction principale
 *
*/
void main( int argc , char *argv[]) 
{
 if (argc > 2) {
   FILE *fp = NULL;
   ULONG cf = 0;
   FlagComp = FALSE; 
   FlagArg  = TRUE;
   OuvreAll();
   for(int i=0;i<134;filename[i++]=0x00);
   char *ptrf = filename;
   strcpy(ptrf,argv[1]);
   Load();
   if (MarqueDecomp) {
     puts("ShowDoc : Décompression...");
     puts("~~~~~~~~");
     if (fp = fopen(argv[2] , "wb")) {
       cf = fwrite(pfp,1,lfp,fp);
       fclose(fp);
       if (cf != lfp)
         PutErr(MSG_ERR_13);
       }
     else
       PutErr(MSG_ERR_9);
   }
   else {
     puts("ShowDoc : Compression...");
     puts("~~~~~~~~");
     int re = PackTxt();
     if (re == 2) {
       FreeMem(Dest,lfp + ENCODEEXTRA(lfp));
     } 
     else {
       if (re == 1) FermeAll();
       else {
         if (fp = fopen(argv[2] , "wb")) {
           char *Marque = "SHOWDOC.LH";
           cf = fwrite(Marque,1,strlen(Marque),fp);
           cf = fwrite(&lfp,1,sizeof(lfp),fp);
           cf = fwrite(Dest,1,LhBuffer -> lh_DstSize,fp);
           fclose(fp);
           if (cf != LhBuffer -> lh_DstSize)
             PutErr(MSG_ERR_13);
         }
         else
           PutErr(MSG_ERR_9);
       } 
     FreeMem(Dest,lfp + ENCODEEXTRA(lfp));
     }
   }
   FermeAll();
 }
 OuvreAll();
 ARexxFlag = TRUE;
 arexxSigBit=initRexxPort();
 if (!arexxSigBit) 
   PutWarn(MSG_ERR_16),ARexxFlag = FALSE;
 if (argc > 1) {
   FlagArg = TRUE;
   int i;
   for(i=0;i<134;filename[i++]=0x00);
   char *ptrf = filename;
   strcpy(ptrf,argv[1]);
   Load();
   FlagArg = FALSE;
 }
 while (TRUE) {
   Wait((1L << fenetre->UserPort->mp_SigBit)| arexxSigBit);
   if(arexxSigBit) {
     dispRexxPort();
     if (FlagAbort) {
       FermeAll();
     } 
   }
   if (message=(struct intuiMessage *)GetMsg(fenetre->UserPort)) {
     classemessage = message->Class;
     ReplyMsg((struct Message *)message);
     switch (classemessage) {
       case MOUSEBUTTONS:
         xmouse = message->MouseX;
         ymouse = message->MouseY;
         if (xmouse >= BOX_QUIT_X1 && xmouse <= BOX_QUIT_X2 &&
             ymouse >= BOX_QUIT_Y2 && ymouse <= BOX_QUIT_Y1) {
           Quitter();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_ABOUT_X1 && xmouse <= BOX_ABOUT_X2 &&
             ymouse >= BOX_ABOUT_Y2 && ymouse <= BOX_ABOUT_Y1) {
           About();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_LOAD_X1 && xmouse <= BOX_LOAD_X2 &&
             ymouse >= BOX_LOAD_Y2 && ymouse <= BOX_LOAD_Y1) {
           Load();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_PAGEDO_X1 && xmouse <= BOX_PAGEDO_X2 &&
             ymouse >= BOX_PAGEDO_Y2 && ymouse <= BOX_PAGEDO_Y1) {
           PageDown();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_PAGEUP_X1 && xmouse <= BOX_PAGEUP_X2 &&
             ymouse >= BOX_PAGEUP_Y2 && ymouse <= BOX_PAGEUP_Y1) {
           PageUp();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_LINEDO_X1 && xmouse <= BOX_LINEDO_X2 &&
             ymouse >= BOX_LINEDO_Y2 && ymouse <= BOX_LINEDO_Y1) {
           AfficheLigneDo();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_LINEUP_X1 && xmouse <= BOX_LINEUP_X2 &&
             ymouse >= BOX_LINEUP_Y2 && ymouse <= BOX_LINEUP_Y1) {
           AfficheLigneUp();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_SAVE_X1 && xmouse <= BOX_SAVE_X2 &&
             ymouse >= BOX_SAVE_Y2 && ymouse <= BOX_SAVE_Y1) {
           Save();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
         if (xmouse >= BOX_PRINT_X1 && xmouse <= BOX_PRINT_X2 &&
             ymouse >= BOX_PRINT_Y2 && ymouse <= BOX_PRINT_Y1) {
           Imprime();
           while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
             ReplyMsg((struct Message *)message);
           break; }
       case RAWKEY:
/*          printf("KEY == %d\n",message->Code); */
          switch (message->Code) {
          case 69:
            Quitter(); 
            while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
              ReplyMsg((struct Message *)message);
            break;
          case 77:
            AfficheLigneDo();
            while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
              ReplyMsg((struct Message *)message);
            break;
          case 76:
            AfficheLigneUp();
            while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
              ReplyMsg((struct Message *)message);
            break;
          case 79:
            PageUp();
            while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
              ReplyMsg((struct Message *)message);
            break;
          case 78:
            PageDown();
            while (message=(struct intuiMessage *)GetMsg(fenetre->UserPort))
              ReplyMsg((struct Message *)message);
            break;
          }
       default:  break;
     }  
   }
 }
}
