/*
 * NameHan.c - Using GET method
 * NameHan.cgi
 * Kim, Jinsuk  [jskim@bioinfo.kordic.re.kr]
 */

#include "NameHan.h"

/* stringÀÌ ¿µ¹®ÀÌ¸é YES, ¾Æ´Ï¸é (ÇÑ±Û ¶Ç´Â Æ¯¼ö¹®ÀÚ) NO¸¦ return */
int IsEnglish(string)
        char *string;
{
        int i;

        for (i=0; i<strlen(string); i++)
        {
                if ( (int)string[i] < 21 || (int)string[i] > 126 )
                {
                        return NO;
                }
        }

        return YES;
}

void PrintMsg(content, align, color)
	char *content;
	char *align;
	char *color;
{
	printf("<p align=\"%s\"><font color=\"%s\">", align, color);
	printf("<b>%s</b></font><p>\n", content);
}

void MakeDic(line, KEdic)
	char		*line;
	KorEngDict	*KEdic;
{
	char	*ptr;
	char	buf[2048];
	char	buf2[2048];
	char	buf3[2048];
	int	x, y;

	for (x=0, y=0; x<strlen(line); x++)
		if (line[x] == ';') y++;
	if (y != 3)
	{
		printf("<font color=red>»çÀü¿À·ù:</font> [%s]<br>\n", line);
		return;
	}

	KEdic->hn=0;
	KEdic->en=0;
	strcpy(buf, line);

	/* ÇÑ±Û¸í ÃßÃâ */
	ptr = (char *) strstr(buf, ";");
	*(ptr) = '\0';
	strcpy(buf2, buf);
	strcpy(buf, ptr+1);
	do {
		if ( !(ptr=(char *)strstr(buf2, ",")) )
		{
			strcpy(KEdic->han[KEdic->hn], buf2);
			KEdic->hn++;
			break;
		}
		*(ptr) = '\0';
		strcpy(buf3, ptr+1);
		strcpy(KEdic->han[KEdic->hn], buf2);
		strcpy(buf2, buf3);
		KEdic->hn++;
	} while (1);

	/* ¿µ¾î¸í ÃßÃâ */
	ptr = (char *) strstr(buf, ";");
	*(ptr) = '\0';
	strcpy(buf2, buf);
	strcpy(buf, ptr+1);
	do {
		if ( !(ptr=(char *)strstr(buf2, ",")) )
		{
			strcpy(KEdic->eng[KEdic->en], buf2);
			KEdic->en++;
			break;
		}
		*(ptr) = '\0';
		strcpy(buf3, ptr+1);
		strcpy(KEdic->eng[KEdic->en], buf2);
		strcpy(buf2, buf3);
		KEdic->en++;
	} while (1);


	/* ÀÌ¸í¹ý ÃßÃâ */
	ptr = (char *) strstr(buf, ";");
	*(ptr) = '\0';
	strcpy(buf2, buf);
	strcpy(buf, ptr+1);
	strcpy(KEdic->sci, buf2);

	/* ¼³¸í ÃßÃâ */
	strcpy(KEdic->desc, buf);
}

void SearchHan(query)
	char	*query;
{
	FILE		*fp;
	KorEngDict	KEdic;
	char		buf[2048];
	int		x, y;
	int		found=0, flag;

	if ( (fp=fopen(KOR_ENG_DICT, "r")) == NULL )
	{
		fclose(fp);
		PrintMsg("ÇÑ¿µ»çÀüÀ» ¿­ ¼ö ¾ø½À´Ï´Ù.", CENTER, RED);
		printf("<h4 align=center><a href=\"mailto:%s\">", WEB_MASTER);
		printf("°ü¸®ÀÚ</a>¿¡°Ô ÆíÁö¸¦ ÁÖ½Ê½Ã¿À.</h4>\n");
		return;
	}

	if ( !strcmp(query, "__¸ðµÎº¸±â__") )
	{
		printf("<dl>\n");
		while (fgets(buf, 2048, fp))
		{
			*(buf+(strlen(buf)-1)) = '\0';
			MakeDic(buf, &KEdic);
			printf("<dt><b>");
			for (x=0; x<KEdic.hn; x++)
			{
				if (x == KEdic.hn-1)
					printf("%s ", KEdic.han[x]);
				else
					printf("%s, ", KEdic.han[x]);
			}
			printf("</b>");
			if (strlen(KEdic.sci) > 0)
				printf("(<i>%s</i>)\n", KEdic.sci);
			printf("<dd><font size=+1>");
			for (x=0; x<KEdic.en; x++)
			{
				trim(KEdic.eng[x]);
				strcpy(buf, KEdic.eng[x]);
				for (y=0; y<strlen(buf); y++)
					if (buf[y] == ' ')
						buf[y] = '+';
				if (buf[0] == '*')
				{
					printf("%d. %s ", x+1, KEdic.eng[x]+1);
					continue;
				}
				printf("%d. <a href=\"%s?qt=%s\">", x+1, \
					CGI_APA_SEARCH, buf);
				printf("%s</a> ", KEdic.eng[x]);
			}
			printf("</font>\n");
			found++;
		}
		printf("</dl>\n");
		return;
	}

	flag = NO;
	printf("<dl>\n");
	while (fgets(buf, 2048, fp))
	{
		*(buf+(strlen(buf)-1)) = '\0';
		MakeDic(buf, &KEdic);
		for (x=0; x<KEdic.hn; x++)
		{
			if (strstr(KEdic.han[x], query))
			{
				flag = YES;
				break;
			}
		}
		if (flag == NO)
			continue;
		printf("<dt><b>");
		for (x=0; x<KEdic.hn; x++)
		{
			if (x == KEdic.hn-1)
				printf("%s ", KEdic.han[x]);
			else
				printf("%s, ", KEdic.han[x]);
		}
		printf("</b>");
		if (strlen(KEdic.sci) > 0)
			printf("(<i>%s</i>)\n", KEdic.sci);
		printf("<dd><font size=+1>");
		for (x=0; x<KEdic.en; x++)
		{
			trim(KEdic.eng[x]);
			strcpy(buf, KEdic.eng[x]);
			for (y=0; y<strlen(buf); y++)
				if (buf[y] == ' ')
					buf[y] = '+';
			if (buf[0] == '*')
			{
				printf("%d. %s ", x+1, KEdic.eng[x]+1);
				continue;
			}
			printf("%d. <a href=\"%s?qt=%s\">", x+1, \
				CGI_APA_SEARCH, buf);
			printf("%s</a> ", KEdic.eng[x]);
		}
		printf("</font><br>%s<p>\n", KEdic.desc);
		found++;
		flag = NO;
	}
	printf("</dl>\n");

	if (found == 0)
	{
		PrintMsg("Ã£´Â °Ë»ö¾î¿¡ ÇØ´çÇÏ´Â Ç×¸ñÀÌ »çÀü¿¡ ¾ø½À´Ï´Ù.", CENTER, RED);
		PrintMsg("µ¿ÀÇ¾î³ª º¸´Ù ÂªÀº ÇüÅÂÀÇ ´Ü¾î¸¦ ÀÔ·ÂÇØº¸½Ê½Ã¿À.", CENTER, GREEN);
		PrintMsg("¿¹: ¹ü -&gt; È£¶ûÀÌ, ÀÌ¸® -&gt; ´Á´ë, ¾Þ¹«»õ -&gt; ¾Þ¹«", CENTER, BROWN);
	}
}

int main()
{
	FILE		*fp;
	getentry	entries[10];
	long int	i, x, y;
	char		query[256];

	strcpy(query, "\0");
	printf("content-type: text/html\n\n");	/* HTML Header */

#ifdef FILEOUT
	printf("Debugging Mode\n");
	i = 0;
	strcpy(entries[0].name, "query");
	strcpy(entries[0].val, "È£¶ûÀÌ");
#else
	i = ProcessGetMethod( entries );
#endif

	for (x=0; x<=i; x++)
	{
		if (!strcasecmp(entries[x].name, "query"))
		{
			strcpy(query, entries[x].val);
			trim(query);
		}
	}

	printf("<HTML>");
       	printf("<HEAD>\n");
	if ( strlen(query) > 0)
       		printf("<TITLE>Bioinfo µ¿¹°±×¸²Ã¢°í °Ë»ö \"%s\"</TITLE>\n", query);
	else
       		printf("<TITLE>Bioinfo µ¿¹°±×¸²Ã¢°í °Ë»ö</TITLE>\n");
       	printf("</HEAD>\n");

	printf("<body bgcolor=\"white\">\n");
	printf("<center><IMG SRC=\"APAsrch.gif\"></center>\n");
        printf("<HR SIZE=5>\n");

	printf("<center><table border=3 cellpadding=5>\n");
	printf("<tr><th>ÇÑ±Û°Ë»ö\n");
	printf("<th>¿µ¾î°Ë»ö\n");
	printf("<tr><td><center>\n");
	printf("<FORM METHOD=\"GET\" ACTION=\"%s\">\n", CGI_HAN_SEARCH);
	printf("<br><INPUT NAME=\"query\" SIZE=20 VALUE=\"%s\">\n", query);
	printf("<INPUT TYPE=submit VALUE=\"°Ë»ö\"><br>\n");
	printf("ÇÑ±Û°Ë»öÀº µ¿¹°ÀÌ¸§ ÇÑ¿µ»çÀüÀ» °Ë»öÇÕ´Ï´Ù. ÇÑ±Û´Ü¾î ÇÏ³ª¸¦ ");
	printf("ÀÔ·ÂÇØÁÖ½Ê½Ã¿À.\nÇÑ±Û¸íÀ» ¸ðµÎ º¸½Ã·Á¸é");
	printf("\n<a href=\"%s?query=__¸ðµÎº¸±â__\">¿©±â</a>", CGI_HAN_SEARCH);
	printf("¸¦\n´­·¯ÁÖ½Ê½Ã¿À.\n");
	printf("</FORM>\n");
	printf("</center>\n");

	printf("<td><center>\n");
	printf("<FORM METHOD=\"GET\" ACTION=\"%s\">\n", CGI_APA_SEARCH);
	printf("<br><INPUT NAME=\"qt\" SIZE=20 VALUE=\"\">\n");
	printf("<INPUT TYPE=submit VALUE=\"Search\"><br>\n");
	printf("<B>Tips:</B>");
	printf("Case-insensitive; Able to use wild card characters <tt>*</tt> and <tt>?</tt>; Singular noun search; \n");
	printf("Examples - <font color=brown><tt>WOLF<font color=blue>*</font>HOWL</tt>, ");
	printf("<tt>ALLIGAT<font color=blue>?</font>R</tt></font>\n");
	printf("</FORM>\n");
	printf("</center>\n");

	printf("</table></center>\n<hr size=5><p>\n");

	if ( strlen(query) > 0 && !IsEnglish(query) )
	{
		SearchHan(query);
	}
	else if ( strlen(query) > 0 && IsEnglish(query) )
	{
		PrintMsg("¿µ¾î´Ü¾î¸¦ ÀÔ·ÂÇÏ¼Ì½À´Ï´Ù.", CENTER, BLUE);
		printf("<h3 align=center>");
		printf("<font color=brown>¿µ¾î</font>·Î Á÷Á¢ °Ë»öÇÏ°íÀÚ ÇÏ¸é");
		printf("<a href=\"%s?qt=%s\">¿©±â(%s)</a>¸¦", CGI_APA_SEARCH, \
			query, query);
		printf("´­·¯ÁÖ½Ê½Ã¿À.</h3>\n");
	}
	else
	{
		PrintMsg("°Ë»öÇÒ ´Ü¾î¸¦ ÀÔ·ÂÇÏ½Ê½Ã¿À", CENTER, BROWN);
	}

        printf("<HR SIZE=5>\n");

	printf("<CENTER><P>\n");
	printf("[ <A HREF=\"%s\">µ¿¹°±×¸²Ã¢°í</A> ]<BR>\n",\
		APA_HOME);
	printf("<HR WIDTH=400 SIZE=5>\n");
	printf("<HR WIDTH=300 SIZE=5>\n");
	printf("<HR WIDTH=200 SIZE=5>\n");

	if((fp=fopen(ACC_NUM_FILE, "r"))==NULL)
                PrintMsg("<I>ÆÄÀÏ¿­±â¿À·ù</I>", CENTER, RED);
	else
	{
		fscanf(fp,"%d", &x);
		fclose(fp);
		printf("%d<p>\n", x);
	}

	if((fp=fopen(ACC_NUM_FILE, "w"))==NULL)
                PrintMsg("<I>ÆÄÀÏ¿­±â¿À·ù</I>", CENTER, RED);
	else
	{
		fprintf(fp,"%d\n",x+1);
		fclose(fp);
	}

	/* query logging */
	if((fp=fopen(QUERY_LOG_FILE, "a"))==NULL)
                PrintMsg("<I>ÆÄÀÏ¿­±â¿À·ù</I>", CENTER, RED);
	else
	{
		fprintf(fp,"%d %s\n", x, query);
		fclose(fp);
	}

	exit(0);
}

/* NCSA Web Library */
void 
getword(char *word, char *line, char stop)
{
	int             x = 0, y;

	for (x = 0; ((line[x]) && (line[x] != stop)); x++)
		word[x] = line[x];

	word[x] = '\0';
	if (line[x])
		++x;
	y = 0;

	while (line[y++] = line[x++]);
}

char           *
makeword(char *line, char stop)
{
	int             x = 0, y;
	char           *word = (char *) malloc(sizeof(char) * (strlen(line) + 1));

	for (x = 0; ((line[x]) && (line[x] != stop)); x++)
		word[x] = line[x];

	word[x] = '\0';
	if (line[x])
		++x;
	y = 0;

	while (line[y++] = line[x++]);
	return word;
}

char           *
fmakeword(FILE * f, char stop, int *cl)
{
	int             wsize;
	char           *word;
	int             ll;

	wsize = 102400;
	ll = 0;
	word = (char *) malloc(sizeof(char) * (wsize + 1));

	while (1)
	{
		word[ll] = (char) fgetc(f);
		if (ll == wsize)
		{
			word[ll + 1] = '\0';
			wsize += 102400;
			word = (char *) realloc(word, sizeof(char) * (wsize + 1));
		}
		--(*cl);
		if ((word[ll] == stop) || (feof(f)) || (!(*cl)))
		{
			if (word[ll] != stop)
				ll++;
			word[ll] = '\0';
			return word;
		}
		++ll;
	}
}

char 
x2c(char *what)
{
	register char   digit;

	digit = (what[0] >= 'A' ? ((what[0] & 0xdf) - 'A') + 10 : (what[0] - '0'));
	digit *= 16;
	digit += (what[1] >= 'A' ? ((what[1] & 0xdf) - 'A') + 10 : (what[1] - '0'));
	return (digit);
}

void 
unescape_url(char *url)
{
	register int    x, y;

	for (x = 0, y = 0; url[y]; ++x, ++y)
	{
		if ((url[x] = url[y]) == '%')
		{
			url[x] = x2c(&url[y + 1]);
			y += 2;
		}
	}
	url[x] = '\0';
}

void 
plustospace(char *str)
{
	register int    x;

	for (x = 0; str[x]; x++)
		if (str[x] == '+')
			str[x] = ' ';
}

int 
rind(char *s, char c)
{
	register int    x;
	for (x = strlen(s) - 1; x != -1; x--)
		if (s[x] == c)
			return x;
	return -1;
}

int 
getline(char *s, int n, FILE * f)
{
	register int    i = 0;

	while (1)
	{
		s[i] = (char) fgetc(f);

		if (s[i] == CR)
			s[i] = fgetc(f);

		if ((s[i] == 0x4) || (s[i] == LF) || (i == (n - 1)))
		{
			s[i] = '\0';
			return (feof(f) ? 1 : 0);
		}
		++i;
	}
}

void 
send_fd(FILE * f, FILE * fd)
{
	int             num_chars = 0;
	char            c;

	while (1)
	{
		c = fgetc(f);
		if (feof(f))
			return;
		fputc(c, fd);
	}
}

/* coded by armian@www.kordic.re.kr */
int
ProcessGetMethod(entries)
getentry	*entries;
{
	char	*cl;
	int	x, m;

	if (strcmp(getenv("REQUEST_METHOD"), "GET"))
        {
                printf("This script should be referenced with a METHOD of GET.\n");
                printf("If you don't understand this, see this ");
                printf("<A HREF=\"http://www.ncsa.uiuc.edu/SDG/Software/Mosaic/Docs/fill-out-forms/overview.html\">forms overview</A>.%c", 10);
                exit(1);
        }

        cl = getenv("QUERY_STRING");
        if ( strlen(cl) <= 0 )
        {
/*
                printf("No query information to decode.\n");
*/
                return -1;
        }

        for (x = 0; cl[0] != '\0'; x++)
        {
                m = x;
                getword(entries[x].val, cl, '&');
                plustospace(entries[x].val);
                unescape_url(entries[x].val);
                getword(entries[x].name, entries[x].val, '=');
        }

	return m;
}
