/* index.c - generate file index
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pwd.h>
#include "mstring.h"
#include "terminal.h"
#include "viewfile.h"


/* Add string "str" to "buf", prefixed by ", " if *f!=0. Sets *f to 1.
 */
void rf__index_perm(char *buf, char *str, long *f)
{
	if (*f)
		strcat(buf, ", ");
	strcat(buf, str);
	*f = 1;
}


/* [I] - view index of current file.
 */
void rf_view_index(rf_data_t data)
{
	char *tmp;
	char tmpbf[1024] = { 0 };
	char buf[sizeof(data->linebuf)];
	char buf2[sizeof(data->linebuf)];
	struct LDB ldb_entry;
	struct stat statbuf;
	struct passwd *p;
	struct tm *t;
	time_t a;
	char *b;
	long n;
	long c;
	int fd;

	if (data->flags & MENU_STATUS_BARINFO)
		return;

	tmp = (char *) malloc(strlen(P_tmpdir) + 32);
	if (!tmp)
		return;
	strcpy(tmp, P_tmpdir);
	strcat(tmp, "/mviewXXXXXX");
	fd = mkstemp(tmp);
	if (fd < 0) {
		remove(tmp);
		free(tmp);
		return;
	}

	t_goto(0, t_rows - 1);
	t_centre(" \035R*** Generating Index - Please Wait ***\035r ");
	t_bored(0);

	memset(&ldb_entry, 0, sizeof(ldb_entry));

	strcpy(ldb_entry.realname, tmp);
	strcpy(ldb_entry.filename, data->ldb_entry->filename);

	n = strlen(data->ldb_entry->filename) - 37;
	if (n < 0)
		n = 0;
	strcpy(tmpbf, data->ldb_entry->filename + n);
	tmp[37] = 0;

	sprintf(buf, "     Filename : %-37s", tmpbf);
	sprintf(buf + 53, "    Line : %ld\n",
		data->ldb_entry->current_line);
	write(fd, buf, strlen(buf));

	fstat(data->fd, &statbuf);
	t = localtime(&(statbuf.st_mtime));
	p = getpwuid(statbuf.st_uid);

	if (data->ldb_entry->current_line >= data->num_lines) {
		n = statbuf.st_size;
	} else {
		n = data->line_pos[data->ldb_entry->current_line].offset;
	}
	sprintf(buf, "        Owner : %-37sPosition : %ld (%ldK)\n",
		p->pw_name, n, n >> 10);
	write(fd, buf, strlen(buf));

	strftime(data->tmp, sizeof(data->tmp), "%a %b %d %H:%M:%S %Y", t);
	sprintf(buf, "Last modified : %-37s    Size : %lld (%lldK)\n",
		data->tmp,
		(unsigned long long) statbuf.st_size,
		((unsigned long long) statbuf.st_size) >> 10);
	write(fd, buf, strlen(buf));

	strcpy(buf, "Permissions   : ");
	c = 0;
	if (data->flags & MENU_STATUS_ADD)
		rf__index_perm(buf, "Add", &c);
	if (data->flags & MENU_STATUS_EDIT)
		rf__index_perm(buf, "Edit", &c);
	if (data->flags & MENU_STATUS_DELETE)
		rf__index_perm(buf, "Delete", &c);
	if (!c)
		strcat(buf, "None");

	strcat(buf, "\n");
	write(fd, buf, strlen(buf));

	strcpy(buf, "\n\n\n                ");
	strcat(buf,
	       "\035CC~~~~~~~~~~~~~~~~~ File header ~~~~~~~~~~~~~~~~~\035CA");
	strcat(buf, "\n\n");
	write(fd, buf, strlen(buf));

	n = 0;
	while ((n < data->num_lines) && (n < 15)) {
		rf_read_line(data, n);
		if (data->line_pos[n].type == MFILE_LINE_DATESTAMP)
			break;
		strcat(data->linebuf, "\n");
		write(fd, data->linebuf, strlen(data->linebuf));
		n++;
	}

	strcpy(buf, "\n\n                \035CC~~~~~~~~~~~~~~~~ ");
	strcat(buf, "Message Index ~~~~~~~~~~~~~~~~\035CA\n\n");
	write(fd, buf, strlen(buf));

	strcpy(buf,
	       "\035UDate\035u         \035UStart\035u \035ULines\035u ");
	strcat(buf, "\035UFrom\035u          \035USubject\035u\n");
	write(fd, buf, strlen(buf));

	while (n < data->num_lines) {
		t_bored(1);

		if (data->line_pos[n].type == MFILE_LINE_DATESTAMP) {

			a = data->line_pos[n].datestamp;

			if (a == 0) {
				strcpy(data->tmp, "*Unknown*");
			} else {
				t = localtime(&a);
				strftime(data->tmp, sizeof(data->tmp),
					 "%b %d %H:%M", t);
			}

			c = n;
			n++;

			sprintf(buf, "%-13s%5ld+", data->tmp, n);

			if (data->line_pos[n].type == MFILE_LINE_FROM) {
				rf_read_line(data, n);
				b = strrchr(data->linebuf, '(');
				if ((!b)
				    || (data->
					flags & MENU_STATUS_ANONYMOUS)) {
					strcpy(data->tmp,
					       (data->
						flags &
						MENU_STATUS_ANONYMOUS)
					       ? "*Anon*" : "*Unknown*");
				} else {
					strncpy(data->tmp, b + 1, 8);
					b = strchr(data->tmp, ')');
					if (b)
						b[0] = 0;
					else
						data->tmp[8] = 0;
				}
				n++;
			} else {
				strcpy(data->tmp,
				       (data->
					flags & MENU_STATUS_ANONYMOUS)
				       ? "*Anon*" : "*Unknown*");
			}

			while ((n < data->num_lines)
			       &&
			       ((data->line_pos[n].type ==
				 MFILE_LINE_BLANK)
				|| (data->line_pos[n].type ==
				    MFILE_LINE_TO))) {
				n++;
				t_bored(1);
			}

			rf_read_line(data, n);
			b = data->linebuf;
			if (strncmp(b, "Subject:", 8) == 0)
				b += 8;
			else if (strncmp(b, "Message:", 8) == 0) {
				data->linebuf[0] = 0;
				n--;
			}
			while (b[0] == ' ')
				b++;
			strcpy(buf2, b);

			while ((n < data->num_lines)
			       && (data->line_pos[n].type !=
				   MFILE_LINE_DATESTAMP)) {
				n++;
				t_bored(1);
			}

			if (n == c)
				n++;

			sprintf(buf + 19, "%-6ld%-14s%s\n", (n - c) - 1,
				data->tmp, buf2);
			write(fd, buf, strlen(buf));

		} else
			n++;
	}

	write(fd, "\n", 1);

	t_bored(0);
	close(fd);

	read_file(&ldb_entry, "File Index",
		  MENU_STATUS_READONLY | MENU_STATUS_BARINFO |
		  MENU_STATUS_BARSENDRPLY, 0);

	remove(ldb_entry.realname);

	rf_redraw = 1;

	free(tmp);
}

/* EOF */
