// --------------------------------------------------------------------------
// Citadel: DoEnter.CPP
//
// .E... command code.

#include "ctdl.h"
#pragma hdrstop

#include "room.h"
#include "filecmd.h"
#include "tallybuf.h"
#include "log.h"
#include "msg.h"
#include "viewlog.h"
#include "net.h"
#include "group.h"
#include "hall.h"
#include "menus.h"
#include "helpfile.h"
#include "blurbs.h"
#include "aplic.h"
#include "miscovl.h"


// --------------------------------------------------------------------------
// Contents
//
// doEnter()	Handles E(nter) command.

extern ConsoleLockC ConsoleLock;


// --------------------------------------------------------------------------
// doEnter(): Handles E(nter) command.

void doEnter(Bool moreYet, char first)
	{
	char done;
	char letter;
	char ich;

	Bool EnterLocal = FALSE, EnterOld = FALSE, EnterFileLinked = FALSE;
	Bool EnterMail = FALSE, EnterGroup = FALSE;

	SetDoWhat(DOENTER);

	if (moreYet)
		{
		first = 0;
		}

	done = TRUE;

	mPrintf(getmsg(221));

	int OptionCounter = 0;

	do
		{
		done = TRUE;

		letter = (char) toupper(first ? first : (ich = (char) iCharNE()));

		if (++OptionCounter == 69)
			{
			mPrintf(getmsg(1294), getmsg(69), spc);
			OptionCounter = 0;
			}

		// allow exclusive mail entry only
		if (!TI()loggedIn && !cfg.unlogEnterOk && (letter != 'E'))
			{
			CRmPrintfCR(getmsg(222));
			break;
			}

		if (letter == 'S' && !(cfg.surnames || cfg.titles))
			{
			letter = 0; 	// force non-recognition
			}

		switch (letter)
			{
			case 'A':
				{
				mPrintfCR(getmsg(245));

				if (!TI()loggedIn)
					{
					CRmPrintfCR(getmsg(246));
					}
				else
					{
					ExeAplic();
					}

				break;
				}

			case 'B':
				{
				mPrintf(getmsg(225));
				if (!TI()CurrentUser->IsEnterBorders() &&
						!TI()CurrentUser->IsSysop())
					{
					CRCRmPrintfCR(getmsg(226));
					return;
					}

				editBorder();
				break;
				}

			case 'C':
				{
				mPrintf(getmsg(227));
				DoEnterConfiguration(FALSE);
				break;
				}

			case 'D':
				{
				mPrintf(getmsg(228));
				SetDoWhat(ENTERDOOR);

				if (!execDoor(letter = (char) iCharNE(), 0))
					{
					Bool NeedMenu = !TI()CurrentUser->IsExpert();

					if (letter == '?')
						{
						oChar('?');
						NeedMenu = TRUE;
						}
					else
						{
						oChar(letter);
						mPrintf(sqst);
						}

					if (NeedMenu)
						{
						if (getMnuOff(M_DOORS, NULL) > 0)
							{
							showMenu(M_DOORS);
							}
						else
							{
							doCR(2);

							doors *theDoor;

							for (theDoor = extDoorList; theDoor; 
									theDoor = (doors *) getNextLL(theDoor))
								{
								if ((!theDoor->SYSOP || TI()CurrentUser->IsSysop()) &&
										(!theDoor->AIDE || TI()CurrentUser->IsAide()) &&
										(!theDoor->CON || (onConsole && !ConsoleLock.IsLocked())) &&
										(!theDoor->DIR || IsRoomDirectory(TI()thisRoom)))
									{
									Bool ShowOnMenu = TRUE;

									if (theDoor->group[0])
										{
										g_slot GroupSlot = 
												FindGroupByName(theDoor->group);

										if (GroupSlot != CERROR)
											{
											if (!TI()CurrentUser->IsInGroup(GroupSlot))
												{
												ShowOnMenu = FALSE;
												}
											}
										}

									if (ShowOnMenu)
										{
										mPrintfCR(getmsg(1390), theDoor->name[0],
												theDoor->name);
										}
									}
								}

							mPrintfCR(getmsg(2));
							}
						}
					else
						{
						doCR();
						}
					}

				break;
				}

			case 'G':
				{
				mPrintf(getmsg(236), cfg.Ugroup_nym);
				done = FALSE;
				EnterGroup = TRUE;
				break;
				}

			case 'H':
				{
				mPrintfCR(pcts, cfg.Uhall_nym);
				enterhall();
				break;
				}

			case 'L':
				{
				mPrintf(getmsg(272));
				done = FALSE;
				EnterLocal = TRUE;
				break;
				}

			case 'E':
				{
				EnterMail = TRUE;

				mPrintf(getmsg(230));

				// handle nomail flag!
				if (!TI()CurrentUser->IsMail())
					{
					CRCRmPrintfCR(getmsg(231), cfg.Lmsgs_nym);
					return;
					}

				// fall through
				}

			case '\r':
			case '\n':
			case 'M':
				{
				mPrintf(pcts, cfg.Umsg_nym);

				// handle readonly flag!
				if (IsRoomReadOnly(TI()thisRoom) &&
						!TI()CurrentUser->HasRoomPrivileges(TI()thisRoom))
					{
					CRCRmPrintfCR(getmsg(223), cfg.Uroom_nym);
					return;
					}

				// handle steeve
				if (	// We are checking (-1 means no check) and...
						cfg.MessageRoom >= 0 &&

						// We have reached our limit and...
						GetMessagesEnteredInRoom(TI()thisRoom) >=
						cfg.MessageRoom &&

						// We are not an Aide.
						!TI()CurrentUser->IsAide()
					)
					{
					CRCRmPrintfCR(getmsg(224), cfg.MessageRoom,
							cfg.MessageRoom == 1 ?
							cfg.Lmsg_nym : cfg.Lmsgs_nym, cfg.Lroom_nym);
					return;
					}

				// user configurability is your friend
				if (!EnterOld && TI()MS.AbortedMessage &&
						TI()CurrentUser->IsConfirmNoEO())
					{
					char prompt[128];

					doCR();
					sprintf(prompt, getmsg(975), cfg.Lmsg_nym);
					if (!getYesNo(prompt, 0))
						{
						return;
						}
					}

				if (EnterOld && !TI()MS.AbortedMessage)
					{
					CRCRmPrintfCR(getmsg(1139), cfg.Lmsg_nym);
					return;
					}

				Message *Msg = new Message;

				if (Msg)
					{
					Bool Massemail = FALSE;

					// let's handle .Enter Old
					if (EnterOld)
						{
						doCR();
						CRmPrintf(getmsg(1140), cfg.Lmsg_nym);

						*Msg = *TI()MS.AbortedMessage;
						Msg->SetCensored(FALSE);	// check later
						}

					if (EnterFileLinked)
						{
						char LinkedFile[64];

						doCR();
						getNormStr(getmsg(1138), LinkedFile, 63, ECHO);

						if (!*LinkedFile)
							{
							delete Msg;
							return;
							}

						Msg->SetFileLink(LinkedFile);
						Msg->SetText(ns);				// .EO*
						}

					if (IsRoomShared(TI()thisRoom))
						{
						Msg->SetLocal(EnterLocal);
						}

					doCR();

					if (EnterMail || (EnterOld && Msg->IsMail()))
						{
						TI()OC.Echo = CALLER;
						setio();

						if (TI()CurrentUser->IsSysop() && EnterGroup)
							{
							Massemail = TRUE;
							}
						else
							{
							EnterGroup = FALSE;

							if (TI()loggedIn)
								{
								char destination[LABELSIZE + LABELSIZE + LABELSIZE + LABELSIZE + 7];
								char defaultdest[LABELSIZE + LABELSIZE + LABELSIZE + LABELSIZE + 7];
								if (*Msg->GetToUser())
									{
									strcpy(defaultdest, Msg->GetToUser());
									if (*Msg->GetDestinationAddress())
										{
										strcat(defaultdest, getmsg(1508));
										strcat(defaultdest,
												Msg->GetDestinationAddress());
										}
									else if (*Msg->GetToNodeName())
										{
										strcat(defaultdest, getmsg(1508));
										strcat(defaultdest,
												Msg->GetToNodeName());
										if (*Msg->GetToRegion())
											{
											strcat(defaultdest, getmsg(1509));
											strcat(defaultdest,
													Msg->GetToRegion());
											}
										}
									}
								else
									{
									*defaultdest = '\0';
									}

								do
									{
									getString(getmsg(1134), destination,
											LABELSIZE + LABELSIZE + LABELSIZE + 6,
											TRUE, ECHO, defaultdest);

									normalizeString(destination);
									stripansi(destination);

									if (*destination == '?')
										{
										ListUsers(TI()CurrentUser->IsAide());
										}
									} while (*destination == '?');

								if (*destination)
									{
									label ToUser, ToNode, ToRegion, ToAddress;
									parseNetAddress(destination, ToUser, ToNode, ToRegion, ToAddress);

									if (!*ToUser)
										{
										strcpy(ToUser, getmsg(1020));
										}

									Msg->SetToUser(ToUser);
									Msg->SetToNodeName(ToNode);
									Msg->SetToRegion(ToRegion);
									Msg->SetDestinationAddress(ToAddress);
									}
								else
									{
									delete Msg;
									return;
									}
								}
							else
								{
								// not logged in? mail only to sysop.
								Msg->SetToUser(getmsg(1020));
								}
							}
						}

					if (EnterGroup)
						{
						label GroupName;

						do
							{
							getString(cfg.Lgroup_nym, GroupName, LABELSIZE,
									TRUE, ECHO, ns);

							if (*GroupName == '?')
								{
								ListGroups(TRUE);
								}
							} while (*GroupName == '?');

						if (*GroupName)
							{
							g_slot GroupSlot;

							GroupSlot = FindGroupByPartialName(GroupName,
									FALSE);

							if (GroupSlot == CERROR ||
									!TI()CurrentUser->IsInGroup(GroupSlot))
								{
								CRmPrintf(getmsg(947), cfg.Lgroup_nym);

								delete Msg;
								return;
								}

							Msg->SetGroup(GroupData->GetEntry(GroupSlot)->GetName());

							if (Massemail)
								{
								Msg->SetToUser(Msg->GetGroup());
								}
							}
						}

					makeMessage(Msg, NULL);

					TI()OC.Echo = BOTH;
					setio();

					delete Msg;
					}
				else
					{
					mPrintf(getmsg(188), getmsg(619));
					}

				break;
				}

			case 'N':
				{
				label NewName;

				SetDoWhat(ENTERNAME);

				mPrintfCR(getmsg(248));

				GetStringWithBlurb(cfg.enter_name, NewName, LABELSIZE,
							TI()CurrentUser->GetName(), B_ENTERNYM);
				normalizeString(NewName);

				if (*NewName)
					{
					if (TI()CurrentUser->IsSysop() ||
							SameString(TI()CurrentUser->GetName(), NewName))
						{
						TI()CurrentUser->SetName(NewName);
						}
					else
						{
						CRmPrintfCR(getmsg(249));
						}
					}

				break;
				}

			case 'O':
				{
				mPrintf(getmsg(237));
				done = FALSE;
				EnterOld = TRUE;
				break;
				}

			case 'P':
				{
				mPrintfCR(getmsg(238));

				if (!TI()loggedIn)
					{
					CRmPrintfCR(getmsg(239));
					return;
					}

				newPW(TRUE);
				break;
				}

			case 'R':
				{
				mPrintfCR(cfg.Uroom_nym);

				if (!TI()loggedIn)
					{
					CRmPrintfCR(getmsg(241), cfg.Lrooms_nym);
					break;
					}

				if (	// The user must be able to make a room
						TI()CurrentUser->IsMakeRoom()  &&

						// And at least one of the of the following...
							(
							cfg.nonAideRoomOk ||
							HallData->GetEntry(TI()thisHall)->IsEnterRoom() ||
							TI()CurrentUser->IsAide()
							)
						)
					{
					// Now check the number made so far...

					if (	// No limit set
							!cfg.numRooms ||

							// Aides get no limits
							TI()CurrentUser->IsAide() ||

							// We haven't reached the limit yet
							TI()roomsMade < cfg.numRooms)
						{
						makeRoom(EnterGroup);
						}
					else
						{
						CRmPrintfCR(getmsg(976), ltoac(cfg.numRooms),
								cfg.Lroom_nym);
						}
					}
				else
					{
					CRmPrintfCR(getmsg(242), cfg.Lrooms_nym);
					}

				break;
				}

			case 'S':
				{
				SetDoWhat(ENTERSUR);

				if (cfg.surnames || cfg.titles) 	// currently redundant
					{
					mPrintf(getmsg(250));

					if (!TI()CurrentUser->IsSysop() && !cfg.entersur)
						{
						CRCRmPrintfCR(getmsg(251), cfg.Uuser_nym);
						return;
						}

					if (!TI()CurrentUser->IsSysop() &&
							TI()CurrentUser->IsSurnameLocked())
						{
						CRCRmPrintfCR(getmsg(252));
						return;
						}

					doCR();

					if (cfg.titles)
						{
						label NewTitle;

						// Note: getmsg(253) also in log3.cpp
						GetStringWithBlurb(getmsg(253), NewTitle, LABELSIZE,
								TI()CurrentUser->GetTitle(), B_TITLESUR);

						if (*NewTitle)
							{
							normalizeString(NewTitle);
							TI()CurrentUser->SetTitle(NewTitle);
							}
						}

					if (cfg.surnames)
						{
						label NewSurname;

						// Note: getmsg(254) also in log3.cpp
						GetStringWithBlurb(getmsg(254), NewSurname, LABELSIZE,
								TI()CurrentUser->GetSurname(), B_TITLESUR);

						if (*NewSurname)
							{
							normalizeString(NewSurname);
							TI()CurrentUser->SetSurname(NewSurname);
							}
						}
					}

				break;
				}

			case 'T':
				{
				mPrintf(getmsg(243));

				if (CheckDirectoryRoom())
					{
					doCR();

					if (!TI()loggedIn)
						{
						mPrintfCR(getmsg(239));
						}
					else if (IsRoomDownloadOnly(TI()thisRoom) &&
							!TI()CurrentUser->HasRoomPrivileges(TI()thisRoom))
						{
						mPrintfCR(getmsg(218), cfg.Uroom_nym);
						}
					else if (!TI()CurrentUser->IsUpload())
						{
						CRmPrintfCR(getmsg(364), getmsg(365));
						return;
						}
					else
						{
						entertextfile(EnterGroup);
						}
					}
				break;
				}

			case 'W':
				{
				mPrintf(getmsg(244));

				if (!CheckDirectoryRoom())
					{
					return;
					}

				if (!TI()CurrentUser->IsUpload())
					{
					CRmPrintfCR(getmsg(364), getmsg(365));
					return;
					}

				// handle downonly flag
				if (IsRoomDownloadOnly(TI()thisRoom) &&
						!TI()CurrentUser->HasRoomPrivileges(TI()thisRoom))
					{
					CRCRmPrintfCR(getmsg(218), cfg.Uroom_nym);
					return;
					}

				if (!TI()loggedIn)
					{
					CRmPrintfCR(getmsg(239));
					return;
					}

				enterwc(EnterGroup);
				break;
				}

			case 'X':
				{
				mPrintf(getmsg(247), cfg.Lroom_nym);
				exclude();
				break;
				}

			case '*':
				{
				mPrintf(getmsg(234));

				if (!TI()CurrentUser->IsSysop())
					{
					CRCRmPrintfCR(getmsg(235), cfg.Lmsgs_nym);
					return;
					}

				done = FALSE;
				EnterFileLinked = TRUE;
				break;
				}

			case ESC:
				{
				break;
				}

			default:
				{
				oChar(ich);
				mPrintf(sqst);

				if (TI()CurrentUser->IsExpert())
					{
					break;
					}
				}

			case '?':
				{
				if (letter == '?')
					{
					oChar('?');
					}

				SetDoWhat(ENTERMENU);

				showMenu(M_ENTOPT);
				break;
				}
			}
		} while (!done && moreYet);
	}
