/*
 * preview.c
 * for Bioinfo Animal Pictures Archive
 * jskim@bulls.kordic.re.kr
 */

#include "preview.h"

int main()
{
	FILE		*fp;
	char		*srcFile, *srcPath;
	char		previewFile[256];
	char		FilePath[256];
	getentry	entries[5];
	int		scaleFactor;	/* Resizing Scale Down Factor */

	char		buf[256];
	char		*ptr;
	register	int	i, x;

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

#ifdef FILEOUT
	printf("Debugging Mode\n");
	i = 2;
	strcpy(entries[0].name, "img");
	strcpy(entries[0].val, "animal5/Wswart37-3wolf.jpg");
	strcpy(entries[1].name, "scaleFactor");
	strcpy(entries[1].val, "104");
#else
	i = ProcessGetMethod( entries );
#endif

	for (x = 0; x <= i; x++)
	{
		if (!strcmp(entries[x].name, "img"))
		{
			strcpy(FilePath, entries[x].val);
			strcpy(buf, entries[x].val);
			while (ptr = (char *)strstr(buf, "/"))
			{
				strcpy(buf, ptr+1);
			}
			srcFile = (char *) malloc(strlen(buf)+1);
			strcpy(srcFile, buf);
			strcpy(buf, entries[x].val);
			ptr = (char *) strstr(buf, srcFile);
			*ptr = '\0';
			srcPath = (char *) malloc(strlen(buf)+1);
			strcpy(srcPath, buf);
			continue;
		}

		if (!strcmp(entries[x].name, "scaleFactor"))
		{
			scaleFactor = atoi(entries[x].val);
			continue;
		}
	}

	if ( !(scaleFactor == 2 || scaleFactor == 4 || scaleFactor == 8))
	{
		scaleFactor = 2;	/* Default to 2 */
	}

	printf("<html>\n");
	printf("<head>\n");
	printf("<title>Preview : %s</title>\n", srcFile);
	printf("</head>\n");
	printf("<body bgcolor=\"white\"><center>\n");
	printf("<h3 align=\"center\">%s<br>Preview 1/%d size</h3>\n",\
		srcFile, scaleFactor);

	strcpy(buf, srcFile);
	for (i = strlen(srcFile); i > 0; i--)
	{
		if (buf[i] == '.')
		{
			buf[i] = '\0';
			break;
		}
	}

	if (strstr(srcFile, ".jpg") || strstr(srcFile, ".JPG"))
	{
		strcpy(previewFile, buf);
		sprintf(buf, "-s%d.jpg", scaleFactor);
		strcat(previewFile, buf);

		sprintf(buf, "%s/%s", PREVIEW_DIR, previewFile);
		if ( (fp=fopen(buf, "r")) == NULL )
		{
			sprintf(buf, "%s -scale 1/%d -gif %s%s | %s > %s/%s",\
				DJPEG, scaleFactor, srcPath, srcFile, CJPEG, \
				PREVIEW_DIR, previewFile);
			if (system(buf) == -1)
			{
				printf("problem in preview...<br>\n");
				printf("<a href=\"ViewImg.cgi?img=%s%s\">",\
					srcPath, srcFile);
				printf("Click here to see full image</a><p>\n");
				exit(1);
			}
		}
	}
	else if (strstr(srcFile, ".gif") || strstr(srcFile, ".GIF"))
	{
		strcpy(previewFile, buf);
		sprintf(buf, "-s%d.gif", scaleFactor);
		strcat(previewFile, buf);

		sprintf(buf, "%s/%s", PREVIEW_DIR, previewFile);
		if ( (fp=fopen(buf, "r")) == NULL )
		{
			sprintf(buf, "%s %s%s | %s -scale 1/%d -gif > %s/%s",\
				CJPEG, srcPath, srcFile, DJPEG, scaleFactor,\
				PREVIEW_DIR, previewFile);
			if (system(buf) == -1)
			{
				printf("problem in preview...<br>\n");
				printf("<a href=\"ViewImg.cgi?img=%s%s\">",\
					srcPath, srcFile);
				printf("Click here to see full image</a><p>\n");
				exit(1);
			}
		}
	}
	else
	{
		printf("The Image %s cannot be previewed.<br>\n", srcFile);
		printf("<a href=\"ViewImg.cgi?img=%s%s\">", srcPath, srcFile);
		printf("Click here to see full image</a><p>\n");
		exit(0);
	}

	printf("<center><table border=2>\n");
	printf("<tr><td><a href=\"ViewImg.cgi?img=%s%s\">", srcPath, srcFile);
	printf("<img alt=\"Click me to view full image.\" src=\"%s/%s\"></tr></td>\n", PREVIEW_DIR, previewFile);
	printf("</table><p>\n");

	switch(scaleFactor)
	{
		case 2:
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=4\">Preview 1/4 size</a>] ", srcPath, srcFile);
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=8\">Preview 1/8 size</a>]<p>", srcPath, srcFile);
			break;
		case 4:
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=2\">Preview 1/2 size</a>] ", srcPath, srcFile);
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=8\">Preview 1/8 size</a>]<p>", srcPath, srcFile);
			break;
		case 8:
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=2\">Preview 1/2 size</a>] ", srcPath, srcFile);
			printf("[<a href=\"preview.cgi?img=%s%s&scaleFactor=4\">Preview 1/4 size</a>]<p>", srcPath, srcFile);
			break;
		default:
			break;
	}

	printf("<hr>\n");
	PrintDescriptionFile(FilePath);
	printf("<font size=+1>\n");
	printf("<p><a href=\"%s\">Go Back To Home</a><p>\n", URL_HOME);
	printf("</font>\n</center>\n</body>\n");
	printf("</html>\n");

	free(srcFile); free(srcPath);

	exit(0);
}

int PrintDescriptionFile(char FilePath[])
{
	FILE *fp;
	int i;
	char		srcFileDesc[256];

	char		buf[256];
	char		buf2[256];

	strcpy(buf, FilePath);
	for (i = strlen(FilePath); i > 0; i--) {
		if (FilePath[i] == '.') {
			buf[i] = '\0';
			break;
		}
	}

	printf("<table><tr><td>\n");
	while (1)
	{
		strcpy(srcFileDesc, buf);
		strcat(srcFileDesc, ".txt");
		if ( (fp=fopen(srcFileDesc, "r")) == NULL ) ;
		else
		{
			printf("<pre>\n");
			while(fgets(buf2, 256, fp))
				PrintLink(buf2);
			printf("</pre>\n");
			fclose(fp);
			break;
		}

		strcpy(srcFileDesc, buf);
		strcat(srcFileDesc, ".TXT");
		if ( (fp=fopen(srcFileDesc, "r")) == NULL ) ;
		else
		{
			printf("<pre>\n");
			while(fgets(buf2, 256, fp))
				PrintLink(buf2);
			printf("</pre>\n");
			fclose(fp);
			break;
		}

		strcpy(srcFileDesc, buf);
		strcat(srcFileDesc, ".html");
		if ( (fp=fopen(srcFileDesc, "r")) == NULL ) ;
		else
		{
			printf("<p>");
			while(fgets(buf2, 256, fp))
				if (!(strstr(buf2, "<img ") || \
					strstr(buf2, "<IMG ")))
					printf("%s", buf2);
			fclose(fp);
			break;
		}
		break;
	}
	printf("</table>\n");


	printf("<hr><p><table border=0 cellspacing=0 cellpadding=0 width=500><tr><td bgcolor=blue>\n");
	printf("<center><font color=white>\n");
	printf("<b>\"This animal was misidentified and I know the correct name.\", \"This animal needs to be further identified.\", <i>Or</i> \"I have some questions or comments.\"</b>");
	printf("<tr><td><center><FORM METHOD=\"POST\" ACTION=\"comment.cgi\">\n");
	printf("<INPUT TYPE=hidden NAME=\"comFile\" VALUE=\"%s\">", FilePath);
	printf("<INPUT TYPE=\"submit\" VALUE=\"Comments about this animal image to the webmaster\">\n</FORM>\n");
	printf("</center></center>\n</table>\n");

	return 0;
}

/* extract URLs in a line and hyperlink it */
int PrintLink(line)
     char *line;
{
	int i, j, k;
	char *ptr;
	char buf[256];

	if ( strstr(line, "From: ") || strstr(line, "from: ") || strstr(line, "Reply-To: ") )
	{
		if (ptr = (char *) strstr(line, "@"))
		{
			i = 1;
			while (*(ptr-i) != ' ' && *(ptr-i) != '(' &&\
				*(ptr-i) != '[' && *(ptr-i) != '<')
			{
				i++;
			}
			j = 1;
			while (*(ptr+j) != ' ' && *(ptr+j) != ')' &&\
				*(ptr+j) != ']' && *(ptr+j) != '>' &&\
				*(ptr+j) != '\n' && *(ptr+j) != '\0')
			{
				j++;
			}

			for (k=0; k < i+j-1; k++)
			{
				buf[k] = *(ptr-i+1+k);
			}
			buf[k] = '\0';

			for (k=0; k<strlen(line)-strlen(ptr-i)+1; k++)
				putchar(line[k]);
			printf("<a href=\"mailto:%s\">%s</a>", buf, buf);
			ptr = (char *) strstr(line, buf);
			printf("%s", ptr+strlen(buf));
			return 1;
		}
		else
			printf("%s", line);
		return 1;
	}
	else if ( (ptr = (char *) strstr(line, "http://")) )
	{
		i = 0;
		while ( *(ptr+i) != '\0' && *(ptr+i) != '\n' && \
			*(ptr+i) != ' ' && *(ptr+i) != ')' && \
			*(ptr+i) != '\"' && *(ptr+i) != '\'' && \
			*(ptr+i) != ']' && *(ptr+i) != '>' )
		{
			buf[i] = *(ptr+i);
			i++;
		}
		buf[i] = '\0';

		for (j=0; j<strlen(line)-strlen(ptr); j++)
			putchar(line[j]);
		printf("<a href=\"%s\">%s</a>", buf, buf);

		ptr = (char *) strstr(line, buf);
		printf("%s", ptr+strlen(buf));
		return 1;
	}
	else if ( (ptr = (char *) strstr(line, "ftp://")) )
	{
		i = 0;
		while ( *(ptr+i) != '\0' && *(ptr+i) != '\n' && \
			*(ptr+i) != ' ' && *(ptr+i) != ')' && \
			*(ptr+i) != '\"' && *(ptr+i) != '\'' && \
			*(ptr+i) != ']' && *(ptr+i) != '>' )
		{
			buf[i] = *(ptr+i);
			i++;
		}
		buf[i] = '\0';

		for (j=0; j<strlen(line)-strlen(ptr); j++)
			putchar(line[j]);
		printf("<a href=\"%s\">%s</a>", buf, buf);

		ptr = (char *) strstr(line, buf);
		printf("%s", ptr+strlen(buf));
		return 1;
	}
	else if ( strstr(line, "Message-Id: ") )
	{
		for (i=0; i<strlen(line); i++)
		{
			if (line[i] == '<')
				printf("&lt;");
			else if (line[i] == '>')
				printf("&gt;");
			else
				printf("%c", line[i]);
		}
	}
	else
		printf("%s", line);
	return 1;
}

/* 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 (cl == NULL)
        {
                printf("No query information to decode.\n");
                exit(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;
}
