/* CalcText by Kouri (Kouri@ucdavis.edu)
 * http://kouri.cjb.net
 * http://void.calc.org
 * 2000.08.12

Program Information:
CalcText will create a file that can be sent to your calculator and viewed with TxtView.
Keeping notes on your calc is now easier than ever! For example, let's say you have a ton
of vocabulary words you have to memorize for a certain class. Simply type them up on your
computer, run the text file through CalcText, and send it to your calc. You can then view
the file using TxtView. See TxtView.asm.txt for more information.

Usage:
For easiest access, place CalcText.exe into a directory that's in your PATH statement.
If you don't know where to put it, put it in C:\WINDOWS\COMMAND
To use the program, first open up a DOS prompt (Start->Programs->MS-DOS Prompt).
Next, you must 'cd' (change directory) into the directory that has your text file in it.
For example: cd\"My Documents"
Then you can type 'calctext <infile> <outfile> ["<description>"]', where
<infile> is the name of the file that you wish to convert.
<outfile> is the name of the file you will send to your calculator.
<description> can be up to 24 characters for the 82/83 and 32 characters for
the 85/86, and should be enclosed with quotes. It will be shown in TxtView's
file selection menu. If no description is given, <outfile> will be used.

Examples:
calctext vocab.txt vocab16.82p "Chapter 16 Physics Vocab"
calctext chem.txt Chemistry.85s "Chemistry test notes"

Credits:
Thomas Hruska, for putting up with all my e-mail asking him for help and for actually
taking the time to help me.
Dan Eble and Andreas Ess, for releasing the source to string85.exe.
Dines Justesen, for also helping me out.
Doug Torrence, for his Hacking the TI-82 columns. */

#include <stdio.h>
#include <string.h>

#define min(a,b)		(((a) < (b)) ? (a) : (b))

#define infilename		argv[1]
#define outfilename		argv[2]
#define description		argv[argc - 1]
#define DESCRIPTION_LENGTH_82	24
#define DESCRIPTION_LENGTH_85	32

/* Function declarations */
void fputc_and_sum(const int);

/* Global variable declarations */
FILE* outfile;
unsigned long checksum = 0;

int main(int argc, char* argv[])
{
 FILE* infile;
 int c, description_length;
 unsigned long i;

 puts("\nTxtView file maker - http://kouri.cjb.net - http://void.calc.org");

 if (argc < 3)
 {
Syntax:
  fputs("Usage: calctext <infile> <outfile> [\"<description>\"]\n", stderr);
  puts("<infile> is the text file you wish to convert.");
  puts("<outfile> is the name of the file you will send to your calculator.");
  puts("<description> can be up to 24 characters for the 82/83 and 32");
  puts("characters for the 85/86, and should be enclosed with quotes.");
  puts("If no description is provided, <outfile> will be used instead.");
  puts("Examples:");
  puts("calctext vocab.txt vocab16.82p \"Chapter 16 Physics Vocab\"");
  puts("calctext chem.txt Chemistry.85s \"Chemistry test notes\"");
  return 1;
 }

/* Open the input file */
 if (!(infile = fopen(infilename, "r")))
 {
  fprintf(stderr, "Error: Can't read file: %s\n", infilename);
  return 2;
 }

/* See what type of file to make
 Anything that ends with a 'p' becomes an 82/83 program file.
 Anything that ends with an 's' becomes an 85/86 string file.
*/
 c = outfilename[strlen(outfilename) - 1]; // c = last char in string
      if (c == 'p') description_length = DESCRIPTION_LENGTH_82;
 else if (c == 's') description_length = DESCRIPTION_LENGTH_85;
 else goto Syntax;

/* Open the output file */
 if (!(outfile = fopen(outfilename, "wb")))
 {
  fprintf(stderr, "Error: Can't write file: %s\n", outfilename);
  return 3;
 }

/* Calculate length of file */
// The 5 is for TxView's file ID (0xFF, 0x00) and EOF (0x00, 0xFF), and the NULL character after the description.
 for (i = 5 + strlen(description); fgetc(infile) != EOF; i++);

/* Write header */
 if (c == 'p') fputs("**TI82**\x1A\x0A", outfile);
 else          fputs("**TI85**\x1A\x0C", outfile);
 fputc(0x00, outfile);

/* Write comment (42 bytes) */
 fputs("TxtView file generated by CalcText - Kouri", outfile);

/* Write number of bytes in file + 17, in reverse order */
 fputc((unsigned char)(i + 17), outfile);
 fputc((i + 17) >> 8, outfile);

 if (c == 'p') fputc_and_sum(0x0B); // Constant for 82p files
 else fputc_and_sum(min(strlen(outfilename), 12)); // Length of string's name + 4?
 fputc(0x00, outfile);

/* Write number of bytes in file + 2, in reverse order */
 fputc_and_sum((unsigned char)(i + 2));
 fputc_and_sum((i + 2) >> 8);

/* Write file type and name */
 if (c == 'p')
  fputc_and_sum(0x06); // Uneditable program file
 else
 {
  fputc_and_sum(0x0C); // String file
  fputc_and_sum(min(strlen(outfilename) - 4, 8)); // Length of string's name
 }
 for (c = 0; argv[2][c] != '.' && c < 8; fputc_and_sum(outfilename[c++]));
 if (outfilename[strlen(outfilename) - 1] == 'p') // Last char in string
  while (c++ < 8) // Fill in the rest with NULLs
   fputc(0x00, outfile);

/* Write more data */
 fputc_and_sum((unsigned char)(i + 2));
 fputc_and_sum((i + 2) >> 8);
 fputc_and_sum((unsigned char)i);
 fputc_and_sum(i >> 8);

/* Write file ID used by TxtView */
 fputc_and_sum(0xFF);
 fputc(0x00, outfile);

/* Write file description */
 for (c = 0; description[c] && c < description_length; fputc_and_sum(description[c++]));
 fputc(0x00, outfile);

/* Write actual text */
 rewind(infile);
 while ((c = fgetc(infile)) != EOF)
  fputc_and_sum(c == '\n' ? 0x00 : c);

/* Write EOF used by TxtView */
 fputc(0x00, outfile);
 fputc_and_sum(0xFF);

/* Write checksum */
 fputc((unsigned char)checksum, outfile);
 fputc(checksum >> 8, outfile);

/* And we're done! */
 printf("File written: %s\n", outfilename);
 return 0;
}

/* Function taken from string85 by Dan Eble - THANKS! */
void fputc_and_sum(c)
{
 fputc(c, outfile);
 checksum += c;
}
