/*****************************************************************************
 *
 * File ..................: mbsetup/m_menu.c
 * Purpose ...............: Edit BBS menus
 * Last modification date : 21-Oct-1999
 *
 *****************************************************************************
 * Copyright (C) 1997-1999
 *   
 * Michiel Broek		FIDO:		2:2801/16
 * Beekmansbos 10		Internet:	mbroek@ux123.pttnwb.nl
 * 1971 BV IJmuiden
 * the Netherlands
 *
 * This file is part of MBSE BBS.
 *
 * This BBS is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * MBSE BBS is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with MBSE BBS; see the file COPYING.  If not, write to the Free
 * Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 *****************************************************************************/

#define	DB_LANG
#define	DB_MENUS

#include "../include/libs.h"
#include "../include/structs.h"
#include "../include/records.h"
#include "../common/common.h"
#include "mutil.h"
#include "screen.h"
#include "ledit.h"
#include "m_lang.h"
#include "m_menu.h"



char *select_menurec(int);
char *select_menurec(int max)
{
	static	char *menu=(char *)"0";
	char	help[81];
	int	pick;

	if (max == 0)
		sprintf(help, "Select ^\"-\"^ for previous level, ^'|A\"^ to append, ^\"D\"^ to delete");
	else
		if (max > 10)
			sprintf(help, "Rec. (1..%d), ^\"-\"^ Back, ^\"A\"^ Append, ^\"D\"^ Delete, ^\"P\"^ or ^\"N\"^ to page", max);
		else
			sprintf(help, "Rec. (1..%d), ^\"-\"^ Back, ^\"A\"^ Append, ^\"D\"^ Delete", max);

	showhelp(help);

	for (;;) {
		mvprintw(LINES - 4, 6, "Enter your choice >");
		menu = (char *)"0";
		menu = edit_field(LINES - 4, 26, 6, '!', menu);
		locate(LINES -4, 6);
		clrtoeol();

		if (strncmp(menu, "A", 1) == 0)
			break;
		if (strncmp(menu, "-", 1) == 0)
			break;
		if (strncmp(menu, "D", 1) == 0)
			break;

		if (max > 10) {
			if (strncmp(menu, "N", 1) == 0)
				break;
			if (strncmp(menu, "P", 1) == 0)
				break;
		}
		pick = atoi(menu);
		if ((pick >= 1) && (pick <= max))
			break;

		working(2, 0, 0);
		working(0, 0, 0);
	}
	return menu;
}



void Show_A_Menu(void);
void Show_A_Menu(void)
{
	clr_index();
	set_color(WHITE, BLACK);
	mvprintw( 5, 2, "8.3. EDIT MENU ITEM");
	set_color(CYAN, BLACK);
	mvprintw( 7, 2, "1.  Sel. key");
	mvprintw( 8, 2, "2.  Type nr.");
	mvprintw( 9, 2, "3.  Opt. data");
	mvprintw(10, 2, "4.  Display");
	mvprintw(11, 2, "5.  Security");
	mvprintw(12, 2, "6.  Min. age");
	mvprintw(13, 2, "7.  Max. lvl");
	mvprintw(14, 2, "8.  Password");
	mvprintw(15, 2, "9.  Credit");
	mvprintw(16, 2, "10. Colors");
	mvprintw(12,42, "11. Autoexec");
	mvprintw(13,42, "12. Menu open");

	set_color(WHITE, BLACK);
	show_str( 7,16, 1, menus.MenuKey);
	show_int( 8,16,    menus.MenuType); show_str( 8, 26,29, menus.TypeDesc);
	show_str( 9,16,64, menus.OptionalData);
	show_str(10,16,64, menus.Display);
	show_sec(11,16,    menus.MenuSecurity);
	show_int(12,16,    menus.Age);
	show_int(13,16,    menus.MaxSecurity);
	show_str(14,16,14, (char *)"**************");
	show_int(15,16,    menus.Credit);
	S_COL(16,16, "Display color", menus.ForeGnd, menus.BackGnd)
	set_color(WHITE, BLACK);
	show_bool(12,56,   menus.AutoExec);
}



int GetSubmenu(int, int);
int GetSubmenu(int Base, int Max)
{
	int	i, x, y;
	char	temp[81];

	clr_index();
	set_color(WHITE, BLACK);
	mvprintw( 4, 2, "7.3 EDIT MENU - SELECT MENUTYPE");
	set_color(CYAN, BLACK);
	y = 6;
	x = 2;

	for (i = 1; i <= Max; i++) {
		sprintf(temp, "%2d. %s", i, getmenutype(i - 1 + Base));
		mvprintw(y, x, temp);
		y++;
		if ((i % 13) == 0) {
			y = 6;
			x = 42;
		}
	}
	i = select_menu(Max);

	if (i)
		return (i + Base - 1);
	else
		return 0;
}



int GetMenuType(void);
int GetMenuType(void)
{
	clr_index();
	set_color(WHITE, BLACK);
	mvprintw( 5, 6, "8.3 EDIT MENU - SELECT MENUTYPE");
	set_color(CYAN, BLACK);
	mvprintw( 7, 6, "1.  Global system menus");
	mvprintw( 8, 6, "2.  File areas menus");
	mvprintw( 9, 6, "3.  Message areas menus");
	mvprintw(10, 6, "4.  User setting menus");
	mvprintw(11, 6, "5.  Oneliner menus");
	mvprintw(12, 6, "6.  BBS List menus");

	switch (select_menu(6)) {
		case 1:	return GetSubmenu(1, 25);
		case 2:	return GetSubmenu(101, 19);
		case 3:	return GetSubmenu(201, 16);
		case 4:	return GetSubmenu(301, 16);
		case 5:	return GetSubmenu(401, 5);
		case 6:	return GetSubmenu(501, 6);
		default: return 0;
	}
}



void Edit_A_Menu(void);
void Edit_A_Menu(void)
{
	Show_A_Menu();

	for (;;) {
		switch(select_menu(12)) {
		case 0:
			return;
			break;

		case 1:	E_UPS( 7,16, 1, menus.MenuKey,   "The ^key^ to select this menu item")
		case 2:
			menus.MenuType = GetMenuType();
			memset(&menus.TypeDesc, 0, sizeof(menus.TypeDesc));
			if (menus.MenuType)
				strcpy(menus.TypeDesc, getmenutype(menus.MenuType));
			Show_A_Menu();
			break;
		
		case 3: E_STR( 9,16,64, menus.OptionalData, "The ^optional data^ for this menu item")
		case 4: E_STR(10,16,64, menus.Display,      "The text to ^display^ for this menu")
		case 5: E_SEC(11,16,    menus.MenuSecurity, "7.3.5 MENU ACCESS SECURITY", Show_A_Menu)
		case 6: E_INT(12,16,    menus.Age,          "The minimum ^Age^ to select this menu, 0 is don't care")
		case 7: E_INT(13,16,    menus.MaxSecurity,  "The maximum ^Security level^ to access this menu")
		case 8: E_STR(14,16,14, menus.Password,     "The ^password^ to access this menu item")
		case 9: E_INT(15,16,    menus.Credit,       "The ^credit cost^ for this menu item")
		case 10:edit_color(&menus.ForeGnd, &menus.BackGnd, (char *)"Display color");
			Show_A_Menu();
			break;
		case 11:E_BOOL(12,56,   menus.AutoExec,     "Is this an ^Autoexecute^ menu item")
		}
	}
}



void EditMenu(char *);
void EditMenu(char *Name)
{
	char		mtemp[81], temp[161];
	FILE		*fil, *tmp;
	int		records = 0, i, o, x, y;
	char		pick[12];
	long		offset;
	unsigned long	crc, crc1;
	int		MenuUpdated = FALSE;

	clr_index();
	IsDoing("Edit Menu");
	working(1, 0, 0);

	sprintf(mtemp, "%s/%s.tmp", lang.MenuPath, Name);
	tmp = fopen(mtemp, "w+");

	sprintf(temp, "%s/%s.mnu", lang.MenuPath, Name);
	if ((fil = fopen(temp, "r")) != NULL) {
		while (fread(&menus, sizeof(menus), 1, fil) == 1) {
			fwrite(&menus, sizeof(menus), 1, tmp);
			records++;
		}
		fclose(fil);
	}

	o = 0;
	for (;;) {
		clr_index();
		working(1, 0, 0);
		sprintf(temp, "8.3 EDIT MENU \"%s\" (%s)", Name, lang.Name);
		mvprintw( 5, 6, tu(temp));
		set_color(CYAN, BLACK);
		fseek(tmp, 0, SEEK_SET);

		if (records) {
			x = 5;
			y = 7;
			for (i = 1; i <= 10; i++) {
				if ((o + i) <= records) {
					offset = ((o + i) - 1) * sizeof(menus);
					fseek(tmp, offset, SEEK_SET);
					fread(&menus, sizeof(menus), 1, tmp);
					if ((menus.MenuKey[0]) || menus.AutoExec) {
						set_color(CYAN, BLACK);
						sprintf(temp, "%3d. %1s %-29s %5d %s", o + i, menus.MenuKey, menus.TypeDesc, menus.MenuSecurity.level, menus.OptionalData);
						temp[74] = '\0';
					} else {
						set_color(LIGHTBLUE, BLACK);
						sprintf(temp, "%3d.", o + i);
					}
					mvprintw(y, x, temp);
					y++;
				}
			}
		}

		working(0, 0, 0);
		strcpy(pick, select_menurec(records));

		if (strncmp(pick, "-", 1) == 0) {
			if (MenuUpdated) {
				if (yes_no((char *)"Menu is changed, save changes") == 1) {
					working(1, 0, 0);
					sprintf(temp, "%s/%s.mnu", lang.MenuPath, Name);
					if ((fil = fopen(temp, "w+")) == NULL) {
						working(2, 0, 0);
					} else {
						fseek(tmp, 0, SEEK_SET);
						while (fread(&menus, sizeof(menus), 1, tmp) == 1) {
							if (menus.MenuKey[0] || menus.AutoExec)
								fwrite(&menus, sizeof(menus), 1, fil);
						}
						fclose(fil);
					}
					working(0, 0, 0);
				}
			}
			fclose(tmp);
			unlink(mtemp);
			return;
		}

		if (strncmp(pick, "A", 1) == 0) {
			working(1, 0, 0);
			memset(&menus, 0, sizeof(menus));
			fseek(tmp, 0, SEEK_END);
			fwrite(&menus, sizeof(menus), 1, tmp);
			records++;
			working(0, 0, 0);
		}

		if (strncmp(pick, "N", 1) == 0)
			if ((o + 10) < records)
				o += 10;

		if (strncmp(pick, "P", 1) == 0)
			if ((o - 10) >= 0)
				o -= 10;

		if ((atoi(pick) >= 1) && (atoi(pick) <= records)) {
			offset = (atoi(pick) - 1) * sizeof(menus);
			fseek(tmp, offset, SEEK_SET);
			fread(&menus, sizeof(menus), 1, tmp);
			crc = 0xffffffff;
			crc = upd_crc32((char *)&menus, crc, sizeof(menus));
			Edit_A_Menu();
			crc1 = 0xffffffff;
			crc1 = upd_crc32((char *)&menus, crc1, sizeof(menus));
			if (crc1 != crc) {
				if (yes_no((char *)"Record is changed, save") == 1) {
					working(1, 0, 0);
					fseek(tmp, offset, SEEK_SET);
					fwrite(&menus, sizeof(menus), 1, tmp);
					MenuUpdated = TRUE;
					working(0, 0, 0);
				}
			}
		}
	}
}



void EditMenus(void)
{
	int	Lang, mcount = 0, i, x, y;
	DIR	*dp;
	struct	dirent *de;
	char	menuname[50][9];
	char	temp[81], pick[12];

	memset(&menuname, 0, sizeof(menuname));
	Lang = PickLanguage((char *)"8.3");
	if (Lang == '\0')
		return;

	if ((dp = opendir(lang.MenuPath)) != NULL) {
		clr_index();
		working(1, 0, 0);
	
		while ((de = readdir(dp))) {
			if (de->d_name[0] != '.') {
				strcpy(menuname[mcount], strtok(de->d_name, "."));
				mcount++;
			}
		}
		closedir(dp);
		working(0, 0, 0);
	}

	for (;;) {
		clr_index();
		set_color(WHITE, BLACK);
		mvprintw( 5, 6, "8.3 MENU EDIT");
		set_color(CYAN, BLACK);
		
		if (mcount) {
			x = 6;
			y = 7;
			set_color(CYAN, BLACK);
			for (i = 1; i <= mcount; i++) {
				sprintf(temp, "%2d. %s", i, menuname[i-1]);
				mvprintw(y, x, temp);
				y++;
				if ((i % 10) == 0) {
					x+=15;
					y = 7;
				}
			}
		}
		strcpy(pick, select_record(mcount, 20));

		if (strncmp(pick, "-", 1) == 0)
			return;

		if (strncmp(pick, "A", 1) == 0) {
		}

		if ((atoi(pick) >= 1) && (atoi(pick) <= mcount))
			EditMenu(menuname[atoi(pick) -1]);
	}
}



int bbs_menu_doc(FILE *fp, FILE *toc, int page)
{
	char	temp[81];
	FILE	*no, *mn;
	DIR	*dp;
	struct	dirent *de;
	int	j;

	sprintf(temp, "%s/etc/language.data", getenv("MBSE_ROOT"));
	if ((no = fopen(temp, "r")) == NULL)
		return page;

	page = newpage(fp, page);
	addtoc(fp, toc, 8, 3, page, (char *)"BBS Menus");

	fread(&langhdr, sizeof(langhdr), 1, no);
	j =0;

	while ((fread(&lang, langhdr.recsize, 1, no)) == 1) {
		if ((dp = opendir(lang.MenuPath)) != NULL) {
			while ((de = readdir(dp))) {
				if (de->d_name[0] != '.') {
					j = 0;
					sprintf(temp, "%s/%s", lang.MenuPath, de->d_name);
					fprintf(fp, "    MENU %s (%s)\n\n", de->d_name, lang.Name);
					if ((mn = fopen(temp, "r")) != NULL) {
						while (fread(&menus, sizeof(menus), 1, mn) == 1) {
							if (menus.MenuKey[0])
								fprintf(fp, "    Menu select   %s\n", menus.MenuKey);
							if (menus.AutoExec)
								fprintf(fp, "    Menu select   Autoexec\n");
							fprintf(fp, "    Type          %d %s\n", menus.MenuType, menus.TypeDesc);
							fprintf(fp, "    Opt. data     %s\n", menus.OptionalData);
							fprintf(fp, "    Display       %s\n", menus.Display);
							fprintf(fp, "    Security      %s\n", get_secstr(menus.MenuSecurity));
							fprintf(fp, "    Minimum age   %d\n", menus.Age);
							fprintf(fp, "    Maximum level %d\n", menus.MaxSecurity);
							fprintf(fp, "    Password      %s\n", menus.Password);
							fprintf(fp, "    Credits       %ld\n", menus.Credit);
							fprintf(fp, "\n\n");
							j++;
							if (j == 5) {
								j = 0;
								page = newpage(fp, page);
							}
						}
						fclose(mn);
					}
					if (j)
						page = newpage(fp, page);
				}
			}
			closedir(dp);
		}
	}

	fclose(no);
	return page;
}



