/* ***********************************************************
Program : Hangul Code Conversion Program
Author :  June-Yub Lee ([email protected]:[email protected])
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;
}