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

char fna[300];
char fnb[300];
char fnc[300];

char s[100];
unsigned char bcd[80];
int icbn[80];
unsigned char cbn[160];

void main(int argc, char **argv)
{
	FILE *fi;
	FILE *foa;
	FILE *fob;
	FILE *foc;
	char *p;
	int ln;
	int i;
	int j;

	if (argc != 2) {
		fprintf(stderr, "Usage: stscvt <file>\n");
		exit(1);
	}
	fi = fopen(argv[1], "r");
	if (fi == NULL) {
		perror(argv[1]);
		exit(1);
	}
	strcpy(fna, argv[1]);
	for (p = &fna[strlen(fna)]; p > fna && *p != '.'; --p);
	if (*p == '.') {
		*p = '\0';
	}
	strcpy(fnb, fna);
	strcpy(fnc, fna);
	strcat(fna, ".txt");
	strcat(fnb, ".bcd");
	strcat(fnc, ".cbn");
	if (strcmp(argv[1], fna) == 0 ||
	    strcmp(argv[1], fnb) == 0 ||
		strcmp(argv[1], fnc) == 0) {
		fprintf(stderr, "File name conflict\n");
		exit(1);
	}
	foa = fopen(fna, "w");
	if (foa == NULL) {
		perror(fna);
		exit(1);
	}
	fob = fopen(fnb, "wb");
	if (fob == NULL) {
		perror(fnb);
		exit(1);
	}
	foc = fopen(fnc, "wb");
	if (foc == NULL) {
		perror(fnc);
		exit(1);
	}

	ln = 0;
	for (;;) {

		// Marker
		if (fgets(s, sizeof(s), fi) != s) {
			break;
		}
		++ln;

		// ASCII
		if (fgets(s, sizeof(s), fi) != s) {
			break;
		}
		++ln;
		fputs(s, foa);

		// EBCDIC hex hi
		if (fgets(s, sizeof(s), fi) != s) {
			break;
		}
		++ln;
		for (i = 0; i < 80; i++) {
			if (s[i] == '\n' || s[i] == 0) {
				fprintf(stderr, "Short hex line %d\n", ln);
				exit(1);
			} else if (s[i] >= '0' && s[i] <= '9') {
				bcd[i] = 0x30 - (((s[i] - '0') << 4) & 0x30);
			} else if (s[i] >= 'A' && s[i] <= 'F') {
				bcd[i] = 0x30 - (((s[i] - 'A' + 10) << 4) & 0x30);
			} else {
				fprintf(stderr, "Invalid hex character <%c> line %d\n",
					s[i], ln);
				exit(1);
			}
		}
		if (s[i] != '\n') {
			fprintf(stderr, "Long hex line %d\n", ln);
			exit(1);
		}

		if (fgets(s, sizeof(s), fi) != s) {
			break;
		}
		++ln;
		for (i = 0; i < 80; i++) {
			if (s[i] == '\n' || s[i] == 0) {
				fprintf(stderr, "Short hex line %d\n", ln);
				exit(1);
			} else if (s[i] >= '0' && s[i] <= '9') {
				bcd[i] |= s[i] - '0';
			} else if (s[i] >= 'A' && s[i] <= 'F') {
				bcd[i] |= s[i] - 'A' + 10;
			} else {
				fprintf(stderr, "Invalid hex character <%c> line %d\n",
					s[i], ln);
				exit(1);
			}
			for (j = 1; j < 0x40; j <<= 1) {
				if (bcd[i] & j) {
					bcd[i] ^= 0x40;
				}
			}
		}
		if (s[i] != '\n') {
			fprintf(stderr, "Long hex line %d\n", ln);
			exit(1);
		}
		bcd[0] |= 0x80;
		fwrite(bcd, 1, 80, fob);

		for (i = 0; i < 80; i++) {
			icbn[i] = 0;
		}
		for (j = 0; j < 12; j++) {
			if (fgets(s, sizeof(s), fi) != s) {
				break;
			}
			++ln;
			for (i = 0; i < 80; i++) {
				if (s[i] == '\n' || s[i] == 0) {
					fprintf(stderr, "Short card line %d\n", ln);
					exit(1);
				} else if (s[i] == '*') {
					icbn[i] |= 1 << (11 - j);
				} else if (s[i] != '.') {
					fprintf(stderr, "Invalid card character <%c> line %d\n",
						s[i], ln);
					exit(1);
				}
			}
			if (s[i] != '\n') {
				fprintf(stderr, "Long card line %d\n", ln);
				exit(1);
			}
		}
		for (i = 0; i < 80; i++) {
			cbn[2*i] = (icbn[i] >> 6) | 0x40;
			cbn[2*i+1] = (icbn[i] & 0x3F) | 0x40;
		}
		for (i = 0; i < 160; i++) {
			for (j = 1; j < 0x40; j <<= 1) {
				if (cbn[i] & j) {
					cbn[i] ^= 0x40;
				}
			}
		}
		cbn[0] |= 0x80;
		fwrite(cbn, 1, 160, foc);
	}
	fclose(fi);
	fclose(foa);
	fclose(fob);
	fclose(foc);
	exit(0);
}
