/* display.c - display menu file
 */

#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <unistd.h>
#include "mstring.h"
#include "terminal.h"
#include "viewmenu.h"
#include "hook.h"


int menuview_rescan_now = 0;
time_t menuview_last_resize = 0;


/* Output the menu footer.
 */
void menuview_footer(menudata_t data)
{

	data->buf[0] = 0;

	if (data->flags & MENUFLAG_SUB) {
		strcpy(data->buf, "[\035BQ\035b]/[\035BRET\035b]:Back  ");
	} else if (!bbs_hook(HOOK_IN_BBS, 0, 0)) {
		strcpy(data->buf, "[\035BQ\035b]:Exit  ");
	}

	if (!(data->flags & MENUFLAG_SPECIAL)) {
		strcat(data->buf, "[\035BSPACE\035b]:Scan  ");
	}

	if (data->offset > 0)
		strcat(data->buf, "[\035B-\035b]  ");
	if (data->menu->num_entries + data->title_lines - data->offset >=
	    t_rows)
		strcat(data->buf, "[\035B+\035b]  ");

	if (data->menu->allow_edit)
		strcat(data->buf, "[\035B.\035b]:Edit  ");

	if (!(data->flags & MENUFLAG_SPECIAL)) {
		strcat(data->buf, "[\035B=\035b]:Opts  ");
	}

	strcat(data->buf, "[\035B?\035b]:Help");
	t_goto((t_cols - mstrlen(data->buf)) / 2, t_rows - 1);
	t_write(data->buf);
}


/* Wipe the menu footer.
 */
void menuview_wipe_footer(menudata_t data)
{
	t_goto(0, t_rows - 1);
	t_clrtoeol();
	t_goto(0, t_rows - 1);
}


/* Output menu entry "e" to the screen.
 */
void menuview_lineout(menudata_t data, menuentry_t * e)
{
	int i, l, showtime, noldb;
	struct stat sb;
	char a[2];
	char *t;

	noldb = 0;

	data->buf[sizeof(data->buf) - 1] = 0;	/* "in case" end-of-string */

	if (e->key == 0) {		    /* centred or repeated text */
		switch (e->type) {

		case MENU_ENTRY_TEXT:	    /* centred text */

			if ((!(e->title)) || (mstrlen(e->title) < 1)) {
				strcpy(data->buf, "\n");
			} else {
				l = (t_cols - mstrlen(e->title)) / 2;
				if (l < 0)
					l = 0;
				if (l > (sizeof(data->buf) - 32))
					l = sizeof(data->buf) - 32;
				for (i = 0; i < l; i++)
					data->buf[i] = ' ';
				data->buf[i] = 0;
				if (e->title) {
					l = sizeof(data->buf) - 32 -
					    strlen(data->buf);
					if (l > 0)
						strncat(data->buf,
							e->title, l);
				}
				strcat(data->buf, "\035a\035CA\035Ca\n");
			}
			t_write(data->buf);
			break;

		case MENU_ENTRY_LINE:	    /* repeated text */

			data->buf[0] = 0;
			l = t_cols;
			if (l < 0)
				l = 0;	    /* should never happen, but... */
			if (l > (sizeof(data->buf) - 32))
				l = sizeof(data->buf) - 32;
			if ((e->title) && (strlen(e->title) > 1)) {
				while (strlen(data->buf) < l) {
					strncat(data->buf, e->title,
						l - strlen(data->buf));
				}
				data->buf[l] = 0;
			}
			strcat(data->buf, "\035a\035CA\035Ca\n");
			t_write(data->buf);
			break;

		default:
			break;
		}
		return;
	}

	showtime = (e->type == MENU_ENTRY_ANIMATION)
	    || (e->type == MENU_ENTRY_BINARY)
	    || (e->type == MENU_ENTRY_COMMENTFILE)
	    || (e->type == MENU_ENTRY_FORMATTED)
	    || (e->type == MENU_ENTRY_READONLY)
	    || (e->type == MENU_ENTRY_UNFORMATTED)
	    || (e->type == MENU_ENTRY_VTANSI);

	if (e->status & MENU_STATUS_NOTIME)
		showtime = 0;
	if (e->status & MENU_STATUS_NOLAST)
		noldb = 1;

	switch (e->type) {
	case MENU_ENTRY_ANIMATION:
		noldb = 1;
		t = "Anim";
		break;
	case MENU_ENTRY_BINARY:
		noldb = 1;
		t = " Bin";
		break;
	case MENU_ENTRY_COMMENTFILE:
	case MENU_ENTRY_FORMATTED:
	case MENU_ENTRY_READONLY:
	case MENU_ENTRY_UNFORMATTED:
	case MENU_ENTRY_VTANSI:
		if (e->status & MENU_STATUS_EDIT)
			t = "Edit";
		else if (e->status & MENU_STATUS_ADD)
			t = " Add";
		else
			t = "    ";
		break;
	case MENU_ENTRY_LISTED:	    /* fall through */
	case MENU_ENTRY_MENU:
		t = "Menu";
		break;
	case MENU_ENTRY_SPOOLED:
	case MENU_ENTRY_EXECUTABLE:
		noldb = 1;
		t = " Run";
		break;
	case MENU_ENTRY_TELNET:
		noldb = 1;
		t = "    ";
		break;
	default:
		t = "    ";
		break;
	}

	l = t_cols / 2;
	if (data->maxlen > l)
		l = t_cols - data->maxlen;
	l -= 30;
	if (l < 0)
		l = 0;
	if (l > (sizeof(data->buf) - 32))
		l = sizeof(data->buf) - 32;
	if (l < 0)
		l = 0;

	for (i = 0; i < l; i++)
		data->buf[i] = ' ';
	data->buf[i] = 0;

	sb.st_mtime = 0;
	i = 1;
	if ((showtime || (!noldb)) && (e->filename))
		i = stat(e->filename, &sb);

	if ((showtime) && (i == 0) && (e->filename)) {
		strcat(data->buf, mstrsince(time(0) - sb.st_mtime));
	} else {
		strcat(data->buf, "                ");
	}

	strcat(data->buf, " ");
	strcat(data->buf, t);
	strcat(data->buf, " ");

	if (e->status & MENU_STATUS_XRATED)
		strcat(data->buf, "\035CR\035FX\035f\035CA");
	else
		strcat(data->buf, " ");

	if (!noldb) {
		i = menu_status(e, data->ldbfile, sb.st_mtime);
	} else
		i = 0;

	if (i & MENU_ITEM_SKIP2)
		strcat(data->buf, "=");
	else if (i & MENU_ITEM_SKIP1)
		strcat(data->buf, "-");
	else
		strcat(data->buf, " ");

	strcat(data->buf, "[\035B");

	a[0] = e->key;
	a[1] = 0;
	strcat(data->buf, a);
	strcat(data->buf, "\035b] ");

	if ((e->type == MENU_ENTRY_LISTED) || (e->type == MENU_ENTRY_MENU)) {
		strcat(data->buf, "= ");
	} else if (i & MENU_ITEM_NOLDB)
		strcat(data->buf, "\035CY*\035CA ");
	else if (i & MENU_ITEM_MODIFIED)
		strcat(data->buf, "\035CR+\035CA ");
	else
		strcat(data->buf, "- ");

	l = (int) (sizeof(data->buf)) - strlen(data->buf) - 16;
	if (l > 0)
		strncat(data->buf, e->title, l);
	if (mstrlen(data->buf) > t_cols) {
		i = mstrindex(data->buf, t_cols - 1);
		strcpy(data->buf + i, "\035R>\035r");
	}

	strcat(data->buf, "\035a\035CA\035Ca\n");
	t_write(data->buf);
}


/* Redraw the screen, regenerating any data that needs regenerating.
 */
void menuview_redraw(menudata_t data)
{
	struct stat sb;
	int i, n, y;

	if (data->last_resize < menuview_last_resize) {
		data->last_resize = menuview_last_resize;
		menuview_rescan_now = 1;
	}

	if (stat(data->file, &sb)) {	    /* stat the menu file */
		data->quit = 3;		    /* quit on failure */
		return;
	}

	if ((menuview_rescan_now) || (sb.st_mtime > data->last_accessed)) {
		menuview_loadmenu(data);    /* reload if modified */
	} else {
		if ((data->menu) && (data->menu->title)) {	/* or if title modified */
			stat(data->menu->title, &sb);
			if (sb.st_mtime > data->last_accessed)
				menuview_loadmenu(data);
		}
	}

	menuview_rescan_now = 0;

	if (data->quit != 0)
		return;

	t_clear();

	y = 0;
	for (i = 0; i < data->title_lines; i++) {
		if (data->titleline[i] == 0) {
			data->buf[0] = 0;
		} else {
			strncpy(data->buf, data->titleline[i],
				sizeof(data->buf) - 8);
			data->buf[sizeof(data->buf) - 8] = 0;
		}
		if (mstrlen(data->buf) > t_cols) {
			n = mstrindex(data->buf, t_cols - 1);
			strcpy(data->buf + n, "\035R>\035r");
		}
		t_write(data->buf);
		t_write("\n");
		y++;
	}

	for (i = data->offset;
	     (i < data->menu->num_entries) && (y < (t_rows - 1)); i++) {
		y++;
		menuview_lineout(data, &(data->menu->menu[i]));
	}

	menuview_footer(data);
}

/* EOF */
