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

#define SYMS 256
#define IOBUF_SIZE 32*1024

Uint ftbl[SYMS];
char ibuf[IOBUF_SIZE];

/* An order 0 encoder file to file demonstration */
int main (int argc, char **argv) {
	int sym;
	rc_encoder rc;
	rc_model rcm;
	FILE *fp, *ofp;
	Uint fsize, i;
	
	if (argc != 3) {
		fprintf(stderr, "Usage:\n%s infile outfile\n", argv[0]);
		exit(1);
	}
	fp = fopen(argv[1], "rb");
	ofp = fopen(argv[2], "wb");
	if (fp && ofp) {
		setvbuf(fp, ibuf, _IOFBF, IOBUF_SIZE);
		if (fseek(fp, 0L, SEEK_END) != 0) {
			fprintf(stderr, "This program only works on files\n");
			exit(1);
		}
		fsize = ftell(fp);
		rewind(fp);
		putc(fsize & 0xff, ofp);  /* Save filesize */
		putc((fsize >> 8) & 0xff, ofp);
		putc((fsize >> 16) & 0xff, ofp);
		putc((fsize >> 24) & 0xff, ofp);
		i = ModelInit (&rcm, SYMS, ftbl, NULL, 2, (Uint)1<<14, ADAPT);
		if (i != RC_OK) {
			fprintf(stderr, "Error: maxFreq or totFreq > 65536\n");
			exit(1);
		}
		StartEncode (&rc, ofp, NULL, 0);
		printf("Encoding...\n");
		fflush(stdout);
		while ((sym = fgetc(fp)) != EOF) {
			EncodeSymbol (&rc, &rcm, sym);
			if (rc.error != RC_OK) break;
		}
		FinishEncode (&rc);
		
		switch (rc.error) {
			case RC_OK:
				printf("Compressed %lu bytes to %lu bytes\n", (unsigned long)fsize, (unsigned long)rc.passed);
				fflush(stdout);
				break;
			case RC_ERROR:
				fprintf(stderr, "Encode error: Symbol outside range\n");
				break;
			case RC_IO_ERROR:
				fprintf(stderr, "Encode error: Could not output compressed data\n");
		}
	}
	fclose(fp);
	fclose(ofp);
	
	return 0;
}
