/********************************************************************
	Code.c v4.0 Copyright © 1993 by Jan Lindström 
  
********************************************************************/

/* Includes */

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

/* Defines */

#define BACK 13

#ifndef NULL
#define NULL 0L
#endif

#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif

#ifndef BOOL
#define BOOL int
#endif

char vers[]="$VER: Code v4 (27-Sep-1993)";

char USAGE[]="CODE USAGE : Code -d|e[vb<kb>] <inputfile> <outputfile>\n\n"   \
        "d       Decode Pc text -> Amiga text\ne       Encode Amiga text -> PC text\n" \
        "v       Verbose mode\nb<kb>    Buffers in kilobytes\n";

/* Funktion prototypes */

void main(int,char **);
void decode(FILE *,FILE *,BOOL);
void encode(FILE *,FILE *,BOOL);

FILE *fp=NULL;
FILE *fp2=NULL;
BOOL verbose=FALSE;
int mode=0;
char *inbuff=NULL;
char *outbuff=NULL;
unsigned long buffsize=10;

void main(int argc,char **argv)
{
    register int j,max;

	printf("%c\x1b[;33mCode v4 \x1b[0m Copyright © 1993 by Jan Lindström.\n\n",12);
	
    if(argc != 4)
    {
        printf("%s",USAGE);
        exit(20);
    }

    if(argv[1][0]=='-')
    {
        max=strlen(argv[1]);

        for(j=1;j < max;j++)
        {
            if(argv[1][j]=='v')
                verbose=TRUE;
            else if(argv[1][j]=='e')
                mode=1;
            else if(argv[1][j]=='d')
                mode=2;
            else if(argv[1][j]=='b')
            {
                j++;
                buffsize=0;
                buffsize=atoi(&(argv[1][j]));

                if(buffsize == 0)
                {
                    mode=0;
                    break;
                }

                while(isdigit(argv[1][j]))
                    j++;
            }
         }   
    }
            
    if(mode == 0)
    {
        printf("%s",USAGE);
        exit(20);
    }
        
    buffsize*=1024;

    if(inbuff=(char *)malloc(buffsize))
    {
        if(outbuff=(char *)malloc(buffsize * 2))
        {
	        if(fp=fopen(argv[2],"r"))
	        {
	            if(fp2=fopen(argv[3],"w"))
	            {
                    if(mode == 2)
	                    decode(fp,fp2,verbose);
                    else
	                    encode(fp,fp2,verbose);
                }
                else
                    printf("Can't open output file %s.\n",argv[3]);
            }
            else
                printf("Can't open input file %s.\n",argv[2]);
        }
        else
            printf("Not enought memory !\n");
    }
    else
        printf("Not enought memory !\n");

    if(inbuff)  free(inbuff);
    if(outbuff) free(outbuff);
	if(fp)      fclose(fp);
    if(fp2)     fclose(fp2);

	printf("Operation done.\n\n");
}

void decode(FILE *fp,FILE *fp2,BOOL verbose)
{
	register unsigned long counter=0,i,j;

	while(i=fread((char *)inbuff,1,buffsize,fp))
	{
		counter+=i;

        for(j=0;j < i;j++)
        {
		    switch(inbuff[j])
		    {
			    case '\x84':	outbuff[j]='ä';break;	    /* ä */
			    case '\x8E':	outbuff[j]='Ä';break;	    /* Ä */
			    case '\x94':	outbuff[j]='ö';break;	    /* ö */
			    case '\x99':	outbuff[j]='Ö';break;	    /* Ö */
                case '\x8F':    outbuff[j]='Å';break;       /* Å */
                case '\x86':    outbuff[j]='å';break;       /* å */
			    case 13:		outbuff[j]=' ';break;	    /* ctrl-m */
			    case '\x1A':	outbuff[j]=' ';break;		/* ctrl-z */
                default:        outbuff[j]=inbuff[j];break;
            }
		}

        if(verbose)
			printf("%cDecoded %ld bytes",BACK,counter);

		fwrite((char *)outbuff,1,j,fp2);
	}

	printf("%cDecoded %ld bytes.\n\n",BACK,counter);
}

void encode(FILE *fp,FILE *fp2,BOOL verbose)
{
	register unsigned long counter=0,i,j,m;

	while(i=fread((char *)inbuff,1,buffsize,fp))
	{
        for(j=0,m=0;j < i;j++,m++)
        {
		    switch(inbuff[j])
		    {
			    case '\xE4':	outbuff[m]=132;break;
			    case '\xC4':    outbuff[m]=142;break;
			    case '\xF6':	outbuff[m]=148;break;
			    case '\xD6':	outbuff[m]=153;break;
                case '\xC5':    outbuff[m]=143;break;
                case '\xA9':    outbuff[m]=134;break;
			    case  10:		outbuff[m]=13;outbuff[++m]=10;break;
                default:        outbuff[m]=inbuff[j];break;
		    }

        }

        counter+=m;

        if(verbose)
		    printf("%cEncoded %ld bytes.",BACK,counter);

		fwrite((char *)outbuff,1,m,fp2);
        
	}

	printf("%cEncoded %ld bytes.\n\n",BACK,counter);
}

