/* edit.c - edit current menu file
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
#include <pwd.h>
#include <ctype.h>
#include "lock.h"
#include "hook.h"
#include "terminal.h"
#include "viewmenu.h"

extern int menuview_abort;


/* Attempt to lock the current file; returns nonzero on failure.
 */
int menuview_edit_lock(menudata_t data)
{
	int tries = 0;
	int newfd;

	newfd = open(data->file, O_RDWR);
	if (newfd < 0)
		return (1);
	close(data->fd);
	data->fd = newfd;

	if (my_flock(data->file, data->fd, LOCK_EX | LOCK_NB) == 0)
		return (0);

	t_goto(0, t_rows - 1);
	t_centre(" \035R *** Waiting for Lock - Please Wait *** \035r ");
	t_bored(0);

	while (tries < 5) {
		t_bored(1);
		sleep(1);
		if (my_flock(data->file, data->fd, LOCK_EX | LOCK_NB) == 0)
			return (0);
		tries++;
	}

	t_goto(0, t_rows - 1);
	t_centre
	    (" \035R *** File is currently locked - try again later *** \035r ");

	return (1);
}


/* Unlock the current file.
 */
void menuview_edit_unlock(menudata_t data)
{
	if (data->fd < 0)
		return;
	my_flock(data->file, data->fd, LOCK_UN);
	close(data->fd);
	data->fd = -1;
}


/* Edit the current file or its title.
 *
 * Just returns if editing is not allowed (!data->menu->allow_edit) or if a
 * file lock could not be obtained.
 */
void menuview_edit(menudata_t data)
{
	int hastitle;
	int hasshell;
	int c;

	if (!data->menu->allow_edit)
		return;

	if (bbs_hook(HOOK_CHECK_BAN, "E", 0)) {
		t_goto(0, t_rows - 1);
		t_clrtoeol();
		t_centre
		    ("\035R  *** You are banned from altering files ***  \035r");
		sleep(2);
		rf_redraw = 1;
		return;
	}

	if (data->status != -1) {	    /* listed directory */
		menuview_edit_listed(data);
		rf_redraw = 1;
		return;
	}

	hastitle = (data->menu->title) ? 1 : 0;
	hasshell = (bbs_hook(HOOK_IS_EXTERNAL, 0, 0)) ? 0 : 1;

	strcpy(data->buf, "[\035BM\035b]/[\035BRET\035b]");
	if (hasshell)
		strcat(data->buf, "/[\035BE\035b]");
	strcat(data->buf, ":Menu");
	if (hastitle) {
		strcat(data->buf, "  [\035BT\035b]");
		if (hasshell)
			strcat(data->buf, "/[\035BV\035b]");
		strcat(data->buf, ":Title");
	}
	strcat(data->buf, "  [\035BQ\035b]:Exit");

	menuview_wipe_footer(data);
	t_goto(0, t_rows - 1);
	t_centre(data->buf);

	do {
		c = toupper(t_getchar(1));
		if (menuview_abort)
			return;
		if (c == 'Q')
			return;
		if ((c == 'T') && (!data->menu->title))
			c = 0;
		if ((c == 'E') && (!hasshell))
			c = 0;
		if ((c == 'V') && (!hasshell))
			c = 0;
		if (c == 13)
			c = 10;
		if (c == 12) {
			rf_redraw = 1;
			c = 0;
		}
		if (rf_redraw) {
			menuview_wipe_footer(data);
			t_goto(0, t_rows - 1);
			t_centre(data->buf);
			rf_redraw = 0;
		}
	} while ((c != 10) && (c != 'M') && (c != 'E') && (c != 'T')
		 && (c != 'V'));

	if ((c == 'T') || (c == 'V')) {
		bbs_hook(HOOK_MENU_ACTION, "Edit Title ",
			 (data->flags & MENUFLAG_HIDETITLE) ? "" : data->
			 title);
		mview_edit_file(data->menu->title, 0, (c == 'T') ? 0 : 1,
				data->title, 0);
		rf_redraw = 1;
		return;
	}

	if (menuview_edit_lock(data))
		return;
	bbs_hook(HOOK_MENU_ACTION, "Edit ",
		 (data->flags & MENUFLAG_HIDETITLE) ? "" : data->title);
	mview_edit_file(data->file, 0, (c == 'E') ? 1 : 0, data->title, 0);
	menuview_edit_unlock(data);

	rf_redraw = 1;
}

/* EOF */
