

#include <dos.h>  /* Just for the current-date routine. */


int common_debug_level_logfile=0;  /* This defaults to 0 for no debugging at all.           */
int common_debug_level_screen=1;   /* Defaults to 1 (print normal messages.                 */
int common_debug_level_current=1;  /* 1 during main(); incremented as functions are called. */
int DEBUG_MESSAGE_TIME_FLAG = 0;   /* By default, don't print time before debug lines. */
                                   /* This time stuff still needs to be implemented! */

int temp_int,error_code;
char temp_char;
char temp_string[150],temp_string_2[150],temp_string_3[150];

/* Define a variable which we can display to clear the screen (ANSI). */
char screen_clear[7]={27,'[','H',27,'[','J',0};
#define screen_goto(row,col) printf("%c[%d;%dH",27,row,col)   /* Cursor positioning. */
#define screen_normal printf("%c[0;37;40m",27)
#define screen_bold printf("%c[1m",27)
#define screen_underline printf("%c[4m",27)
#define screen_blink printf("%c[5m",27)
#define screen_reverse printf("%c[7m",27)
#define screen_concealed printf("%c[8m",27)
#define screen_black_text printf("%c[30m",27)
#define screen_red_text printf("%c[31m",27)
#define screen_green_text printf("%c[32m",27)
#define screen_yellow_text printf("%c[33m",27)
#define screen_blue_text printf("%c[34m",27)
#define screen_magenta_text printf("%c[35m",27)
#define screen_cyan_text printf("%c[36m",27)
#define screen_white_text printf("%c[37m",27)
#define screen_black printf("%c[40m",27)
#define screen_red printf("%c[41m",27)
#define screen_green printf("%c[42m",27)
#define screen_yellow printf("%c[43m",27)
#define screen_blue printf("%c[44m",27)
#define screen_magenta printf("%c[45m",27)
#define screen_cyan printf("%c[46m",27)
#define screen_white printf("%c[47m",27)

FILE *common_log_file;
char common_log_filename[64]="";  /* This should be set by the program.  If none set, then no log file! */
char STX_string[2]={2,0},FS_string[2]={28,0},ETX_string[2]={3,0},
     EOT_string[2]={4,0},ENQ_string[2]={5,0},ACK_string[2]={6,0},  /* For holding constants. */
     CTRL_C_string[2]={3,0};
char CR_string[2]  ={13,0};
char LF_string[2]  ={10,0};
char CRLF_string[3]={13,10,0};
char BELL_string[2]={7,0};
char ESC_character=27;


void screen_drawbox (int y1, int x1, int y2, int x2)
/* draw a single line Ansi art box with top left corner x1,y1 and */
/* bottom right corner x2,y2 */
{
int i;
printf("%c[s",27);                /* Save the screen position.    */
screen_goto(y1,x1); printf("Ú");  /* Draw the corners of the box. */
screen_goto(y2,x1); printf("À");
screen_goto(y1,x2); printf("¿");
screen_goto(y2,x2); printf("Ù");
for(i=x1+1;i<x2;i++)              /* Draw the top and bottom.     */
  {
  screen_goto(y1,i); printf("Ä");
  screen_goto(y2,i); printf("Ä");
  }
for(i=y1+1;i<y2;i++)              /* Draw the sides of the box.   */
  {
  screen_goto(i,x1); printf("³");
  screen_goto(i,x2); printf("³");
  }
printf("%c[u",27);                /* Restore the cursor position. */
}


void screen_drawdoublebox (int y1, int x1, int y2, int x2)
/* draw a double line Ansi art box with top left corner x1,y1 and */
/* bottom right corner x2,y2 */
{
int i;
printf("%c[s",27);                /* Save the screen position.    */
screen_goto(y1,x1); printf("É");  /* Draw the corners of the box. */
screen_goto(y2,x1); printf("È");
screen_goto(y1,x2); printf("»");
screen_goto(y2,x2); printf("¼");
for(i=x1+1;i<x2;i++)              /* Draw the top and bottom.     */
  {
  screen_goto(y1,i); printf("Í");
  screen_goto(y2,i); printf("Í");
  }
for(i=y1+1;i<y2;i++)              /* Draw the sides of the box.   */
  {
  screen_goto(i,x1); printf("º");
  screen_goto(i,x2); printf("º");
  }
printf("%c[u",27);                /* Restore the cursor position. */
}


void pause(void)
{
char pause_string[100];
printf("\nHit <Return> to continue: ");
gets(pause_string);
}


void pad_field_with_spaces(char the_field[],int field_length)
{
int temp_pointer=0;
while (temp_pointer < field_length)
  {
  if (the_field[temp_pointer] == 0)
    the_field[temp_pointer] = ' ';
  temp_pointer++;
  }
}


void get_field_xy(char the_field[],int field_length,char *the_default,int row,int col)
{
int temp_int=0;
memset(the_field,0,field_length);     /* Fill field with nulls.               */
screen_goto(row,col);                 /* Go to right place on screen.         */
while (temp_int++ < field_length)     /* Fill field on screen with "." marks. */
  printf(".");
screen_goto(row,col);                 /* Back to start of field.     */
printf("%s",the_default);             /* Print default, if any.      */
screen_goto(row,col);                 /* Now go get input from user. */
gets(temp_string);
if (!temp_string[0])                  /* User just hit return?       */
  strncpy(the_field,the_default,sizeof(field_length));   /* Return default. */
else
if (strcmp(temp_string," "))          /* Anything except a single space entered? */
  strncpy(the_field,temp_string,field_length);   /* Return info. user entered.   */
/* A single space, to zap the field's contents, was entered. */
screen_goto(row,col);
temp_int = 0;
while (temp_int < field_length)    /* Blank the field on the screen. */
  printf(" ");
}


void show_field(char *the_field,int field_length)
{
char temp_field[150];
temp_field[0] = 0;
strncat(temp_field,the_field,field_length);
printf("%s",temp_field);
}


int get_numeric_input(void)
{
char the_input[8];
int temp;
gets(the_input);
temp = atoi(the_input);
return(temp);
}


long get_dollar_amount(void)   /* Returns number of cents, actually. */
{
char the_input[16];
long temp;
printf("$");
gets(the_input);
temp = atol(the_input);
printf("Amount entered: %8.2f\n",(float)temp / 100);
return(temp);
}

short get_percentage_amount(void)   /* Returns hundredths of percent. */
{
char the_input[16];
short temp;
printf("%");
gets(the_input);
temp = atoi(the_input);
printf("Amount entered: %8.2f\n",(float)temp / 100);
return(temp);
}

long get_quantity_amount(void)  /* Returns, like dollar amount, a long with 2 decimal places.      */
{                               /*  Accepts, however, the input with or without the decimal point. */
char the_input[16],*temp_ptr;
long temp_long=0;
gets(the_input);
temp_ptr = strtok(the_input,".");
if (temp_ptr != NULL)
  temp_long += atol(temp_ptr) * 100;
temp_ptr = strtok(NULL,".");
if (temp_ptr != NULL)
  temp_long += atol(temp_ptr);
return(temp_long);
}

long get_long_input(void)
{
char the_input[16];
long temp;
gets(the_input);
temp = atol(the_input);
return(temp);
}

long divide_with_round(double amount,double divisor)
{
long result;
float resultf,temp;
result  = amount / divisor;
resultf = amount / divisor;
temp = resultf - result;
if (temp < 0)
  temp *= -1;
if (temp >= .5)
  result++;
/* printf("Division results: %f / %f = %ld\n",amount,divisor,result); */
return(result);
}


int common_set_log_filename(char the_filename[])  /* Returns 0 if filename ok, 1 if bad. */
{
common_log_file = fopen(the_filename,"a+b");
if (common_log_file == NULL)
	return(1);                   /* Bad filename! */
fclose(common_log_file);
strcpy(common_log_filename,the_filename);
return(0);
}


void common_write_log_record(char error_message[])
{
common_log_file = fopen(common_log_filename,"a+b");
fseek(common_log_file,0,SEEK_END);
fwrite(error_message,strlen(error_message),1,common_log_file);
fwrite(CRLF_string,2,1,common_log_file);
fclose(common_log_file);
}


void common_debug_message(int common_debug_level_current,char the_message[])
{
int indentation_spaces_printed=0;
if ((common_debug_level_current <= common_debug_level_logfile) && (common_log_filename[0]))
	{
    common_log_file = fopen(common_log_filename,"a+b");
    fseek(common_log_file,0,SEEK_END);
    while (++indentation_spaces_printed < common_debug_level_current)
		fwrite(" ",1,1,common_log_file);                 /* Indent one space for each function call level. */
    fwrite(the_message,strlen(the_message),1,common_log_file);
	fwrite(CRLF_string,2,1,common_log_file);
	fclose(common_log_file);
	}
indentation_spaces_printed = 0;
if (common_debug_level_current <= common_debug_level_screen)
	{
    while (++indentation_spaces_printed < common_debug_level_current)
		printf(" ");                 /* Indent one space for each function call level. */
	printf("%s\n",the_message);
	}
}

void common_debug_message_w_no(int common_debug_level_current,char the_message[],long the_number)
{
int indentation_spaces_printed=0;
char temp_string[16];
if ((common_debug_level_current <= common_debug_level_logfile) && (common_log_filename[0]))
	{
    common_log_file = fopen(common_log_filename,"a+b");
    fseek(common_log_file,0,SEEK_END);
    while (++indentation_spaces_printed < common_debug_level_current)
		fwrite(" ",1,1,common_log_file);
    fwrite(the_message,strlen(the_message),1,common_log_file);
	ltoa(the_number,temp_string,10);
    fwrite(temp_string,strlen(temp_string),1,common_log_file);
	fwrite(CRLF_string,2,1,common_log_file);
	fclose(common_log_file);
	}
indentation_spaces_printed = 0;
if (common_debug_level_current <= common_debug_level_screen)
	{
  while (++indentation_spaces_printed < common_debug_level_current)
    printf(" ");        /* Indent one space for each function call level. */
	printf("%s %ld\n",the_message,the_number);
	}
}



void fatal_error(char *error_message)
{
printf("*** A FATAL PROGRAM ERROR HAS OCCURRED ***\n\n");
printf("%s\n\n",error_message);
/* printf("\nThe last Indexed File Engine error code was %d, in case that's relevant.\n\n",I_F_RESULTCODE); */
printf("It is not your fault!  Please call programming now!  Do not touch\n");
printf("the computer if at all possible.  If not, then write down what you\n");
printf("were doing when the error occurred and all the information the\n");
printf("program reported about the error, including the above error message,\n");
printf("before continuing.  After that, do NOT enter the system which caused\n");
printf("the error!\n\n%c%c%c",7,7,7);
pause();
exit(1);
}


/*-------------------------- Date stuff ------------------------------*/

char date_yymmdd[6];
long date_julian_since_01_01_1900;
int days_in_january=0,
    days_in_february=0,
    days_in_march=0,
    days_in_april=0,
    days_in_may=0,
    days_in_june=0,
    days_in_july=0,
    days_in_august=0,
    days_in_september=0,
    days_in_october=0,
    days_in_november=0,
    days_in_december=0;

void date_print(char *yymmdd)
{
char yy[3],mm[3],dd[3];
if (!yymmdd[0])     /* Don't print anything if there's no date there. */
  return;
yy[2]=0;
mm[2]=0;
dd[2]=0;
memcpy(yy,yymmdd+0,2);
memcpy(mm,yymmdd+2,2);
memcpy(dd,yymmdd+4,2);
printf("%s/%s/%s",mm,dd,yy);
}

void date_input(void)
{
char temp_string[100],yy[2],mm[2],dd[2];
gets(temp_string);
memcpy(mm,temp_string+0,2);
memcpy(dd,temp_string+2,2);
memcpy(yy,temp_string+4,2);
if ( (memcmp(yy,"90",2) < 0) ||
     (memcmp(yy,"99",2) > 0) ||
     (memcmp(mm,"01",2) < 0) ||
     (memcmp(mm,"12",2) > 0) ||
     (memcmp(dd,"01",2) < 0) ||
     (memcmp(dd,"31",2) > 0) )
  {
  memset(date_yymmdd,0,sizeof(date_yymmdd));
  return;
  }
memcpy(date_yymmdd+0,yy,2);
memcpy(date_yymmdd+2,mm,2);
memcpy(date_yymmdd+4,dd,2);
}

int julian_month_from_yymmxx(char *yymmdd)
{
char yy[3],mm[3];
int temp_yy,temp_mm;
strncpy(yy,yymmdd+0,2);
strncpy(mm,yymmdd+2,2);
temp_yy = atoi(yy);
temp_mm = atoi(mm);
return((temp_yy * 12) + temp_mm);
}

void yymmxx_from_julian_month(int julian_month)  /* Returns global variable date_yymmdd. */
{
char yy[3],mm[3];
int temp_yy,temp_mm;
temp_yy = julian_month / 12;
temp_mm = julian_month % 12;
itoa(temp_yy,yy,10);
itoa(temp_mm,mm,10);
memcpy(date_yymmdd+0,yy,2);
memcpy(date_yymmdd+2,mm,2);
memcpy(date_yymmdd+3,"01",2);
}

/*
long convert_yymmdd_to_julian(char *yymmdd)
{
}
void convert_julian_to_yymmdd(long julian_date)
{
}
*/

/* A few time-oriented routines follow. */

void wait(int seconds)
{
time_t starting_time,ending_time;
starting_time = time(NULL);
ending_time = starting_time + seconds + 1;
while (time(NULL) < ending_time)  {};  /* Just wait here until then. */
}

time_t ending_time;  /* For saving times between routines. */

void timeout_set(int seconds)
{
ending_time = time(NULL) + seconds + 1;
}

int timeout_reached(void)
{
if (time(NULL) > ending_time)
  return(1);
return(0);
}


/*---------------------- Print File Stuff ----------------------------*/

FILE *print_file;
int print_lines_per_page=66,print_lines_per_screen=24,print_lines_this_page=0;
char print_destination[32];
char print_record[140],print_pause_string[32],
     print_abort_flag;  /* If 'Y', then skip any printing to screen. */

void print_open(void)  /* Implement filename later, for spooling. */
{
printf("Send report to 's'creen, 'p'rinter, or 'f'ile? ");
gets(print_destination);
if (!strcmp(print_destination,"f"))
  {
  printf("Enter (carefully) the filename to print to: ");
  gets(print_destination);
  }
else
if (toupper(print_destination[0]) == 'P')
  {
  strcpy(print_destination,"PRN");
  }
else
  {
  strcpy(print_destination,"CON");
  printf("%s",screen_clear);
  }
print_file = fopen(print_destination,"wt");
if (print_file == NULL)
  return;
print_lines_this_page = 0;
print_abort_flag = 'N';
}

void print_line(void)
{
if (print_abort_flag == 'Y')
  return;
fprintf(print_file,"%s\n",print_record);
print_lines_this_page++;
if (strcmp(print_destination,"CON"))  /* Destination is not screen. */
  {
  if (print_lines_this_page >= (print_lines_per_page - 4))
    {
    while (print_lines_this_page++ < print_lines_per_page)  /* Finish page. */
      fprintf(print_file,"\n");
    fprintf(print_file,"\n\n\n\n");
    print_lines_this_page = 4;
    }
   else
    {  /* Not near end of page, so do nothing! */  }
  }
 else                                   /* Destination is screen. */
  {
  if (print_lines_this_page >= (print_lines_per_screen - 2))
    {
    printf("'Q'uit, or <Return> to continue: ");
    gets(print_pause_string);
    if (toupper(print_pause_string[0] == 'Q'))
      print_abort_flag = 'Y';
    printf("%s",screen_clear);
    print_lines_this_page = 0;
    }
  }
}

void print_fill(int to_column)
{
while (strlen(print_record) < to_column)
  strcat(print_record," ");
}

void print_blank(void)
{
print_record[0]=0;
print_line();
}

void print_formfeed(void)
{
if (strcmp(print_destination,"CON"))   /* Not printing to screen? */
  while (print_lines_this_page++ < print_lines_per_page)  /* Finish page. */
    fprintf(print_file,"\n");
}

void print_close(void)
{
if (strcmp(print_destination,"CON"))
  print_formfeed();
else
  pause();
fclose(print_file);
}

/*--------------------------- Log File Stuff ---------------------------------*/

char log_record[150];
FILE *log_file;

void log_file_append(char *log_file_name)
{
log_file = fopen(log_file_name,"a+t");
fprintf(log_file,"%s\n",log_record);
fclose(log_file);
}


