/* ***********************************************************
 Program : Hangul Code Conversion Program
 Author :  June-Yub Lee (jylee@math1.nyu.edu:jylee@math1.kaist.ac.kr)
 Created : Jan, 07, 1992
 Modified : Ver. 1.1  Feb, 29, 1992 

 This Program is free software under the GNU General Public License.
 If you are installing this program for your own work or other users,
 please send me a e-mail so that I can fix any possible bug and
 update for new Hangul Code including UNICODE.
************************************************************ */

#include <stdio.h>
#include "hcode.h"
#include "h3Bcode.h"

extern void opt_check();
extern void rmprolog();
extern void printout();
extern void code2conv();
extern void m2code();
extern  int getOne();
extern  int HanCode();
extern  int strNcmp();

main(argc,argv)
int argc;
char *argv[];
{
	FILE *fpin, *fpout;
	unsigned char c,c2=0,ST,EN,buf[MAXBUFSIZE];
	int inCode, outCode, IC, Hanbuf[MAXHANSIZE];

	buf[0] = 0;
	Hanbuf[0] = 0;

	opt_check(argc,argv,&inCode,&outCode, &fpin, &fpout);

	IC = inCode - NB;  /* MultiByte Hangul Input if IC >= 0 */
	if ( inCode == IS ) {
		ST = '\016';
		EN = '\017';
		rmprolog("\033$)C",fpin,fpout);
	} else if ( IC >= 0 ) {
		ST = (unsigned char) StartCode[IC][0];
		EN = (unsigned char) EndCode[IC][0];
	} else { 
		ST = (unsigned char) EOF;
		EN = (unsigned char) EOF;
	}

	while ( (c=getc(fpin)) != (unsigned char) EOF ) {
		if ( c>=0x80 && inCode==TR ||
		    (c==0xa4||c>=0xb0&&c<=0xc8) && inCode==KS ) {
			if (  (c2=getc(fpin)) == (unsigned char) EOF ) {
				fprintf(stderr,"Uncompeleted 2-byte Hangul\n");
				putc(c,fpout);
				ungetc(c2,fpin);
			}	/* Unfinshed 2B Hangul */
			Hanbuf[++Hanbuf[0]] = c*256 + c2;

		} else if ( c==ST && inCode==IS ) {
			while ( (c=getc(fpin)) != EN ) {
				/* Error Dealing Section missing */
				c2=getc(fpin);
				Hanbuf[++Hanbuf[0]] = (c+0x80)*256 + (c2+0x80);
			}

		} else if ( c==ST && IC>=0 ) {
			while ( (c=getc(fpin)) != EN ) {
				if ( c==(unsigned char) EOF ) {
					fprintf(stderr,"Can't find EndCode in MultiByte Hangul\n");
					ungetc(c,fpin);
					break;
				}	/* EndCode Missing */
				buf[++buf[0]] = c;
				if ( buf[0]>=MAXBUFSIZE-5 )
					m2code(buf,IC,MULHAN,Hanbuf);
			}
			m2code(buf,IC,ENDHAN,Hanbuf);

		} else {
			if ( Hanbuf[0]!=0 ) 
				printout(Hanbuf, fpout, inCode, outCode, 1);
			putc(c,fpout);
		}
	}

	if ( Hanbuf[0] != 0 ) {		/* document ending with Hangul */
		printout(Hanbuf, fpout, inCode, outCode, 1);
	}
	fclose(fpin);
	fclose(fpout);
}

/* ------------------------------------------------------
	Command Line Option Check Routine
	Two integes Return : inCode and outCode
	Two file pointer   : fhin, fhout
	Defaults : from_IS, to_KS, stdin, stdout;
  ------------------------------------------------------- */

void opt_check(argc, argv, inCode, outCode, fhin, fhout)
char *argv[];
FILE **fhin, **fhout;
int argc, *inCode, *outCode;
{
	char *program = argv[0];
	*inCode = IS;
	*outCode = KS;
	while (--argc) {
		argv++;
		if ( argv[0][0]!='-' || argv[0][1]=='\0' ) {
			break;
		} else if ( argv[0][2]=='\0' ) {
			*inCode = in_choice [ argv[0][1]-'a' ];
		} else if ( argv[0][3]=='\0' ) {
			*inCode = in_choice [ argv[0][1]-'a' ];
			*outCode = out_choice [ argv[0][2]-'a' ];
		} else  {
			fprintf(stderr,"Unknown Option: %s %s\n",program,syn);
			exit(-1);
		}
		if ( *inCode == 0 ) {
			fprintf(stderr,"Unknown InCode: %s %s\n",program,syn);
			exit(-1);
		} else if ( *outCode == 0 ) {
			fprintf(stderr,"Unknown OutCode: %s %s\n",program,syn);
			exit(-1);
		}
	}

	*fhin = stdin;
	*fhout = stdout;
	if ( argc > 2 ) {
		fprintf(stderr,"Unknown Syntax: %s %s\n",program,syn);
		exit(-1);
	} else if ( argc == 2 ) {
		if ( argv[0][0]!='-' && (*fhin=fopen(argv[0],"r"))==NULL ) {
   			fprintf(stderr,"%s: Read Err on %s\n",program,argv[0]);
   			exit(1);
		}
		if ( (*fhout=fopen(argv[1],"w")) == NULL ) {
   			fprintf(stderr,"%s: Write Err on %s\n",program,argv[1]);
   			exit(1);
		}
	} else if ( argc == 1 ) {
		if ( argv[0][0]!='-' && (*fhin=fopen(argv[0],"r"))==NULL ) {
   			fprintf(stderr,"%s: Read Err on %s\n",program,argv[0]);
   			exit(1);
		}
	}
}

/* ------------------------------------------------------
	Search for Starting Mark and print out (ENGLISH) prologue
	mark : Starting Code
	Two file pointer   : fhin, fhout
  ------------------------------------------------------- */

void rmprolog(mark,fpin,fpout)
char mark[];
FILE *fpin, *fpout;
{
	char c;
	int i,p=0,len=strlen(mark);

	while( (c=getc(fpin)) !=EOF ) {
		if (c==mark[p]) {
			if (p==len-1) 
				return;
			else
				p++;
		} else {
			for ( i=0; i<p; i++ )
				putc(mark[i],fpout);
			p=0;
			putc(c,fpout);
		}
	}
	fprintf(stderr,"Input Err: Can't find Code Starting Point\n");
	ungetc(c,fpin);
}

/* ------------------------------------------------------
	Hangul Output Routine
	putend : in order to end Multibyte Hangul Mode
	stat : PRNONE - Multibyte Start wasn't printed
	     : PRINTED - at least one Hangul was printed in MB mode
  ------------------------------------------------------- */

void printout(Hanbuf, fpout, inCode, outCode, putend)
FILE *fpout;
int inCode, outCode, Hanbuf[], putend;
{
	int i;
	static int stat=PRNONE;

	if ( CODE2(inCode) != CODE2(outCode) )
		code2conv(Hanbuf, CODE2(inCode), CODE2(outCode) );

	if ( outCode==IS ) {
		if ( stat==PRNONE ) {
			fputs("\033$)C",fpout);
			stat=PRINTED;
		}
		putc('\016',fpout);
		for ( i=1; i<=Hanbuf[0]; i++) {
			putc((Hanbuf[i]>>8)-0x80,fpout);
			putc((Hanbuf[i]&0xff)-0x80,fpout);
		}
		putc('\017',fpout);
	} else if ( outCode<NB ) {
		for ( i=1; i<=Hanbuf[0]; i++) {
			putc(Hanbuf[i]>>8,fpout);
			putc(Hanbuf[i]&0xff,fpout);
		}
	} else {
		int C=(outCode-NB),ch,ju,jo;
		for ( i=1; i<=Hanbuf[0]; i++) {
			ch = ( Hanbuf[i] >> 10 ) & 0x1f;
			ju = ( Hanbuf[i] >>  5 ) & 0x1f;
			jo = ( Hanbuf[i]       ) & 0x1f;
			if ( stat == PRNONE )
				fprintf(fpout,"%s",StartCode[C]);
			if ( ch==01 || ju==02 ) {
			    if (stat == PRINTED)
				fprintf(fpout,"%s%s",EndCode[C],StartCode[C]);
			    fprintf(fpout,"%s%s%s%s",ChoSung[ch][C],
				JungSung[ju][C],JongSung[jo][C],EndCode[C]);
			    stat = PRNONE;
			} else {
			    fprintf(fpout,"%s%s%s",ChoSung[ch][C],
				JungSung[ju][C],JongSung[jo][C]);
			    stat = PRINTED;
			}
		}
		if (stat == PRINTED && putend == 1) {
			fprintf(fpout,"%s",EndCode[C]);
			stat = PRNONE;
		}
	}
	Hanbuf[0] = 0;
}