/* prf_print.c  */
/* V1.1 14-3-92 */

#include "prf.h"

char  *dayname[]=
       {
        T_SUNDAY,T_MONDAY,T_TUESDAY,T_WEDNESDAY,T_THURSDAY,T_FRIDAY,T_SATURDAY
       };
char  *monthname[]=
       {
        T_JAN,T_FEB,T_MAR,T_APR,T_MAY,T_JUNE,T_JULY,T_AUG,T_SEP,T_OCT,T_NOV,T_DEC
       };

long BuildStatusline(struct prf_info *,UBYTE *);
long CheckFile(struct prf_info *,UBYTE *);
long PopFile(struct prf_info *,UBYTE *);
void PushFile(struct prf_info *,UBYTE *);
long PrintText(struct prf_info *,UBYTE *);


void PrintQueue(struct prf_info *info)
{
 long     end = FALSE;
 UBYTE    filename[256];
 FILE    *display = NULL;
 info->flags |= FLAG_PRINT;
 if(info->Swd)GT_SetGadgetAttrs(info->SGadgets[GD_Print],info->Swd,NULL,GA_Disabled,TRUE,TAG_DONE);
 if(info->Pwd)GT_SetGadgetAttrs(info->PGadgets[GD_PPrint - PGD],info->Pwd,NULL,GA_Disabled,TRUE,TAG_DONE);
 if(info->Swd)
 {
  SwdTags[0].ti_Data = (ULONG)info->Swd->LeftEdge;
  SwdTags[1].ti_Data = (ULONG)info->Swd->TopEdge;
 }
 sprintf(filename,"CON:%ld/%ld/%ld/%ld/%s",
                   SwdTags[0].ti_Data,SwdTags[1].ti_Data,
                   SwdTags[2].ti_Data,info->BarHeight * 4,T_DISPLAYNAME);
 if((info->flags & FLAG_DISPLAY) && ((info->Pwd) || (info->Swd)))
    display = fopen(filename,"w");
 while (!end  && PopFile(info,filename))
 {
  if(display)fprintf(display,"\n%s",filename);
  switch(CheckFile(info,filename))
  {
   case FILE_TEXT : if(PrintText(info,filename) == CMD_QUIT) end = TRUE;
                    info->Special1 = (APTR)filename;
                    RemoveName(info);
                    info->Special1 = NULL;
                    break;
   case FILE_ILBM : if(display)fprintf(display,ERROR_ILBM);break;
   case FILE_FTXT : if(display)fprintf(display,ERROR_FTXT);break;
   case FILE_PROG : if(display)fprintf(display,ERROR_PROG);break;
   case FILE_ICON : if(display)fprintf(display,ERROR_ICON);break;
   case FILE_DIR  : if(display)fprintf(display,ERROR_DIR);break;
   default        : end = TRUE;
                    break;
  }
 }
 if(display) fclose(display);
 if(info->Pwd)GT_SetGadgetAttrs(info->PGadgets[GD_PPrint - PGD],info->Pwd,NULL,GA_Disabled,FALSE,TAG_DONE);
 if(info->Swd)GT_SetGadgetAttrs(info->SGadgets[GD_Print],info->Swd,NULL,GA_Disabled,FALSE,TAG_DONE);
 info->flags ^= FLAG_PRINT;
}

long PrintText(struct prf_info *info,UBYTE *name)
{
 long rc     = CMD_NEUTRAL;
 long line   = 0;
 long lines  = 1;
 long page   = 1;
 long offset = 0;
 FILE *printer;
 FILE *file;
 UBYTE buffer[STR_SIZE];
 long end = FALSE;
 if(file = fopen(name,"r"))
 {
  if(printer = fopen("prt:","w"))
  {
   if(info->Columns <= 0L) info->Columns = 1L;
   if(info->flags & FLAG_DRAFT)  fprintf(printer,"\x1b[1\x22z");
   if(info->flags & FLAG_LQ)     fprintf(printer,"\x1b[2\x22z");
   if(info->flags & FLAG_PITCH6) fprintf(printer,"\x1b[1z");
   if(info->flags & FLAG_PITCH8) fprintf(printer,"\x1b[0z");
   if(info->flags & FLAG_10CPI)  fprintf(printer,"\x1b[0w");
   if(info->flags & FLAG_12CPI)  fprintf(printer,"\x1b[0w\x1b[2w");
   if(info->flags & FLAG_15CPI)  fprintf(printer,"\x1b[0w\x1b[4w");
   fprintf(printer,"\x1b[%ld;%lds",info->Lmargin,info->Rmargin);
   offset = BuildStatusline(info,name);
   while(!end)
   {
    if(fgets(buffer,STR_SIZE,file))
    {
     if(DoCommand(info,HandleMsgs(info)) == CMD_QUIT)
     {
      end = TRUE;
      rc  = CMD_QUIT;
     }
     if(line == (info->Lines - offset))
     {
      if(*(info->Footline))
      {
       fprintf(printer,"%s\n",info->Footline);
       if (strlen(info->Footline) > info->Columns) line += strlen(info->Footline)/info->Columns;
      }
      if(info->flags & FLAG_PAGE) fprintf(printer,"*** " T_PAGE ": %5d ***",page);
      fprintf(printer,"\f");
      line = 0;line = 0;page++;
     }
     if(line == 0)
     {
      if(*(info->Statusline))
      {
       fprintf(printer,"%s\n",info->Statusline);
       if (strlen(info->Statusline) > info->Columns) line += strlen(info->Statusline)/info->Columns;
      }
      if(info->Headline)
      {
       fprintf(printer,"%s\n\n",info->Headline);
       if (strlen(info->Headline) > info->Columns) line += strlen(info->Headline)/info->Columns;
      }
     }
     if(info->flags & FLAG_LINE)
     {
      fprintf(printer,"%5d:%s",lines,buffer) ;
      if (strlen(buffer) > info->Columns) line += strlen(buffer)/info->Columns;
     }
     else
     {
      fprintf(printer,"%s",buffer);
      if (strlen(buffer) > info->Columns) line += strlen(buffer)/info->Columns;
     }
     if(info->flags & FLAG_CRLF) fprintf(printer,"\n");
     line++,lines++;
    }
    else end = TRUE;
   }
   if(*(info->Footline))fprintf(printer,"%s\n",info->Footline);
   if(info->flags & FLAG_PAGE) fprintf(printer,"*** %5d " T_PAGES T_PRINTED "***\n",page);
   if(info->flags & FLAG_FF) fprintf(printer,"\f");
   fclose(printer);
  }
  else
  {
   PushFile(info,name); /* file not found */
  }
  fclose(file);
 }
 return rc;
}

long CheckFile(struct prf_info *info, UBYTE *name)
{
 long rc = FILE_TEXT;
 struct FileInfoBlock *fib;
 BPTR fh,lock;
 if(stricmp(name + (strlen(name) - 5), ".info"))
 {
  if(fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB,NULL))
  {
   if(lock = Lock(name,ACCESS_READ))
   {
    if(Examine(lock,fib))
    {
     if(fib->fib_DirEntryType > 0)
     {
      rc = FILE_DIR;
     }
     else
     {
      if(!(fib->fib_Protection & FIBB_SCRIPT))
      {
       if(fh = Open(name,MODE_OLDFILE))
       {
        UBYTE b[10];
        if(Read(fh,b,4))
        if(!(strnicmp(b,"\00\00\03\f3",4)))
        {
         rc = FILE_PROG;
        }
        if( (!(strnicmp(b,"form",4))) || (!(strnicmp(b,"list",4))) ||
            (!(strnicmp(b,"prop",4))) || (!(strnicmp(b,"cat" ,3)))
          )
        {
         Read(fh,b,4);  /* read length of file */
         Read(fh,b,4);  /* read form type */
         if(!(strnicmp(b,"ftxt",4)))rc = FILE_FTXT;
          else if(!(strnicmp(b,"ilbm",4)))rc = FILE_ILBM;
           else rc = FILE_UNKNOWN;
        }
        Close(fh);
       }
      }
     }
    }
    UnLock(lock);
   }
   FreeDosObject(DOS_FIB,(APTR)fib);
  }
 }
 else rc = FILE_ICON;
 return rc;
}

long PopFile(struct prf_info *info,UBYTE *name)
{
 long rc = FALSE;
 struct FileNameNode *fnn;
 DetachList(info);
 if(fnn = (struct FileNameNode *)RemHead(&info->FileList))
 {
  if(*(fnn->fnn_Name))
  {
   rc = TRUE;
   strcpy(name,fnn->fnn_Name);
   free(fnn);
  }
 }
 AttachList(info);
 return rc;
}

void PushFile(struct prf_info *info,UBYTE *name)
{
 struct FileNameNode *fnn;
 if(*name)
 {
  if(fnn = calloc(1,sizeof(struct FileNameNode)))
  {
   strcpy(fnn->fnn_Name,name);
   fnn->fnn_Node.ln_Name = fnn->fnn_Name;
   DetachList(info);
   AddHead(&info->FileList,(struct Node *)fnn);
   AttachList(info);
  }
 }
}

long BuildStatusline(struct prf_info *info,UBYTE *name)
{
 long rc = 0;
 char buffer1[STR_SIZE],buffer2[STR_SIZE],buffer3[STR_SIZE];
 long t;
 struct tm *date;
 time(&t);
 date = localtime(&t);
 *buffer1 = '\0';
 *buffer2 = '\0';
 *buffer3 = '\0';
 if(info->flags & FLAG_DATE) sprintf(buffer1,DATE_FORMAT);
 if(info->flags & FLAG_TIME) sprintf(buffer2,TIME_FORMAT);
 if(info->flags & FLAG_FILE) sprintf(buffer3,NAME_FORMAT);
 if((*(buffer1)) || (*(buffer2)) || (*(buffer3)))
 {
  sprintf(info->Statusline,"*** %s%s%s ***",buffer1,buffer2,buffer3);
  rc += 1;
 }
 if(info->flags & FLAG_PAGE)rc += 1;
 if(*(info->Headline))rc += 2;
 if(*(info->Footline))rc += 1;
 return rc;
}


