/*-------------------------------------------------------------------------*/
/*   Programmer:  George Kerber                                            */
/*      Written:  06/19/89                                                 */
/*      Purpose:  Similar to the UNIX Fortune, but centers the lines.      */
/*     Compiler:  Lattice 5.05                                             */
/*-------------------------------------------------------------------------*/

#define WRITTEN "06/19/89 - 04/20/90"
#define VERSION "v2.04h"

#define TRUE 1

#include <stdio.h>
#include <string.h>
#include <dos.h>
#include <ctype.h>
#include <stdlib.h>

void main(), helpscreen(), mistake(), cleanup(), makeline(), print_rule();

void main(int argc, char *argv[])
{
char officialrule[200]  = "Multiple color options", option, opts[] = "";
char *tempy, node[35], pathtorules[80] = "s:fortunes";
int next, character, linesflag = 1, sflag = 0;
int escape_char = '*', cflag = 2, cflag1 = 0;
unsigned char clock[8];
unsigned long linecount; 
FILE *fp, *voice;

/*----- Sets escape value -------- default is * ---------------------------*/
if((tempy = getenv("ESCAPE")) != NULL) escape_char = *tempy;
/*-------------------------------------------------------------------------*/
      
getclk(clock);
stcgfn(node,argv[0]);
if(strcmp(argv[1],"?") == 0 && argc > 1) 
   helpscreen(escape_char,node,pathtorules);

/*----  Error Checking and Option Check  ----------------------------------*/
if(argc)
   {
   for( next = 1 ; (argopt(argc,argv,opts,&next,&option)) != NULL ; )
      {
      switch(toupper(option))
         {
         case '1':  if(cflag1) mistake(officialrule,node); cflag=1; cflag1=1;
                    break;
         case '2':  if(cflag1) mistake(officialrule,node); cflag=2; cflag1=1;
                    break;
         case '3':  if(cflag1) mistake(officialrule,node); cflag=3; cflag1=1;
                    break;
         case 'S':  sflag = 1; break;
         case 'L':  linesflag = 0; break;
          default:  mistake("Invalid Option",node);
         }
      } 
   }

if(!argc)
   {
   *node = NULL;
   sflag = 1;
   }

if(sflag)
   {
   if((voice = fopen("SPEAK:OPT/d0", "w")) == (FILE *)NULL) 
      mistake("Can't open SPEAK:    Is it MOUNTED?",node);
   }

if(sflag) linesflag = 0;
if(argc > next) 
   {
   strcpy(pathtorules,(argv[next]));
   }
   else
   {
   if(!access("ram:fortunes",0)) 
      {
      strcpy(pathtorules,"ram:fortunes");
      }
      else
      {
      if(!access("fortunes",0)) strcpy(pathtorules,"fortunes"); 
      }
   }

if(argc > (next + 1)) mistake("Invalid Option Count",node);

if(access(pathtorules,4)) mistake("Can't Locate File",node);

/*----  Open "fortunes" file    -------------------------------------------*/
if((fp = fopen(pathtorules,"r")) == (FILE *)NULL)
   mistake("Can't Open File",node);

srand(clock[7] + clock[6] + clock[3] + clock[4]);

fseek(fp,-1L,2);
linecount = ftell(fp);
rewind(fp);

while(TRUE)
   {
   if(fseek(fp, (rand() % linecount) + 1, 0))
      {
      mistake("Can't SEEK",node); 
      }

   while((character = fgetc(fp)) != EOF) 
      {
      if(character == '\n') break; 
      continue; 
      }

   if(fgets(officialrule,200,fp) == (char *)NULL)
      {
      continue; 
      }
      else 
      {
      if(*officialrule == ' ' || *officialrule == '#') continue;
      if(linesflag) makeline(cflag);
      if(!sflag) printf("\n");
      print_rule(81,officialrule,escape_char,sflag,voice);
      }

   next = 0;
   while(TRUE) 
      {
      if(fgets(officialrule,200,fp) == (char *)NULL) 
         {
         cleanup(linesflag,sflag,cflag);
         }
         else 
         {
         if(*officialrule != ' ' || *officialrule == '\n') 
            {
            cleanup(linesflag,sflag,cflag); 
            }
         print_rule(80,officialrule,escape_char,sflag,voice);
         if(next++ >= 10) cleanup(linesflag,sflag,cflag);
         }
      continue; 
      }
   if(linesflag) makeline(cflag);
   }
}

/*-------------------------------------------------------------------------*/
/*      End of main program, functions are below                           */
/*-------------------------------------------------------------------------*/

/*  CLEANUP FUNCTION  */

void cleanup(int linesflag,int sflag,int cflag)
{
if(linesflag) makeline(cflag);
if(!sflag) printf("\n");
fcloseall();
exit(0);
}

/*-------------------------------------------------------------------------*/

/*  HELPSCREEN FUNCTION  */

void helpscreen(char escape_char, char *node, char *def_file)
{
char *display = "  displayed w/";
char *outline = " outline.";
char *alter = "alternate path/file";
char *blank = "           -";

printf("\x0c");
makeline(2);
printf("\n  [33m[1m%s[0m    George Kerber %10s %25s\n\n",
       node,VERSION,WRITTEN);
printf("  Randomly display or speak a [33mfortune[0m.\n\n");
printf("  Escape Character = \"[1m[33m%c[0m\"\n\n",escape_char);
printf("  SYNTAX:  [33m%s[0m [-l | -s | [-1 | -2 | -3]] [%s][0m\n\n",
          node,alter);
printf("%ss  spoken --> SPEAK: device.\n",blank);
printf("%sl%so%s\n",blank,display,outline);
printf("%s1%scolor 1%s\n",blank,display,outline);
printf("%s2%s[32mcolor 2[0m%s (default)\n", blank,display,outline);
printf("%s3%s[33mcolor 3[0m%s\n\n", blank,display,outline);
printf("  Data file is [33m%s[0m or %s.\n",def_file,alter);
makeline(2);
printf("\n");
exit(0);
}

/*-------------------------------------------------------------------------*/

/*  MAKELINE FUNCTION  */

void makeline(int cflag)
{

switch(cflag)
   {
   case 1:  printf("[31m"); break;
   case 2:  printf("[32m"); break;
   case 3:  printf("[33m"); break;
   }

printf("[1m  ___________________________________________________________________________[0m\n");
}

/*-------------------------------------------------------------------------*/

/*  MISTAKE FUNCTION  */

void mistake(char *description, char *node)
{
if(*node != NULL)
   {
   printf("\n\n\07     [0mERROR: %s -->[33m> %s.[0m\n\n",
           node,description);
   }
   
exit(5);
}

/*-------------------------------------------------------------------------*/

/*  PRINT_RULE FUNCTION  */

void print_rule(int number, char *rule,int escape_char,int sflag,FILE *voice)
{
int offset = 0, i;
char fortune[200];

*fortune = NULL;

rule--;
while(*(++rule) != (char *)NULL) 
   {
   if(*rule == escape_char) 
      {
      if(*(++rule) == escape_char) 
         {
         i = strlen(fortune);
         *(fortune + i++) = escape_char;
         *(fortune + i) = NULL;
         offset++;
         continue; 
         }
      if(!sflag) 
         {
         switch(*rule) 
            {
            case '0':  strcat(fortune,"[30m"); break; /* color 0 char    */
            case '1':  strcat(fortune,"[31m"); break; /* color 1 char    */
            case '2':  strcat(fortune,"[32m"); break; /* color 2 char    */
            case '3':  strcat(fortune,"[33m"); break; /* color 3 char    */
            case '4':  strcat(fortune,"[0m");  break; /* default attr    */
            case '5':  strcat(fortune,"[1m");  break; /* bold char       */
            case '6':  strcat(fortune,"[4m");  break; /* underline char  */
            case '7':  strcat(fortune,"[3m");  break; /* italics char    */
            case ')':  strcat(fortune,"[40m"); break; /* color 0 bkgnd   */
            case '!':  strcat(fortune,"[41m"); break; /* color 1 bkgnd   */
            case '@':  strcat(fortune,"[42m"); break; /* color 2 bkgnd   */
            case '#':  strcat(fortune,"[43m"); break; /* color 3 bkgnd   */
            }
         }
      }
      else 
      {
      i = strlen(fortune);
      *(fortune + i++) = *rule;
      *(fortune + i) = NULL;
      offset++;
      }
   continue;
   }

if(sflag)
   {
   fprintf(voice,"%s",fortune);
   }
   else
   {
   offset = ((number - offset) / 2);
   for( ; offset > 0 ; strins(fortune," "),offset--); 
   printf("%s[0m",fortune);  
   }
}

/*-------------------------------------------------------------------------*\

10/07/89 v2.03:  Added escape and color options
11/01/89 v2.03b: Re-compiled with Lattice 5.04.
01/07/90 v2.03c: Removed all global variables
03/03/90 v2.04e: Re-compiled with Lattice 5.04.
04/16/90 v2.04g: Optimized code and reduced helpscreen for smaller
                 program size.

\*-------------------------------------------------------------------------*/
