-- File: IntAnswerCom.Mesa
-- edited by Horning, February 27, 1979 5:45 PM
-- edited by Brotz, March 4, 1983 12:04 PM
-- edited by Levin, February 13, 1981 4:33 PM
-- edited by Schroeder, Wednesday Nov. 5, 1980 3:06 pm PST

DIRECTORY
Answer USING [Block, MakeHeader],
Editor USING [RefreshSoThatFirstCharStartsLine, ResetInsertionBuffer,
SwapMessageWithDeletionBuffer],
exD: FROM "ExceptionDefs" USING [answerIncomplete, cantAnswer, DisplayException,
willReplaceMessage],
Inline USING [LowHalf],
intCommon USING [actionPoint, cForCopies, cmTextNbr,
commandType, composedMessageEdited, deliverCommandHouse,
deliverCommandVisible, editorType, newTargetSelection, pendingDeleteSetByControl,
runCommandMode, source, target, tocTextNbr, user],
inD: FROM "InteractorDefs" USING [AskUserToConfirm, CharIndex, HousePtr,
MessageTextNbrPtr, TextHouseRefresher, TextSelection],
prD: FROM "ProtectionDefs" USING [UnprotectAllFields],
Storage USING [FreePages, Pages],
tsD: FROM "TOCSelectionDefs" USING [FirstSelectedEntry, TOCSelectionEmpty],
vmD: FROM "VirtualMgrDefs" USING [AllocateDisplayMessageObject, CharIndex,
ComposedMessage, ComposedMessagePtr, DisplayMessagePtr, FlushDisplayMessage,
FreeVirtualMessageObject, GetMessageChar, GetMessageSize, InitComposedMessage,
InsertSubstringInMessage, LoadDisplayMessage, StartMessageInsertion,
StopMessageInsertion, TOCHandle, UnlockTOC, WaitForLock];

IntAnswerCom: PROGRAM
IMPORTS Answer, Editor, exD, Inline, intC: intCommon, inD, prD, Storage, tsD, vmD
EXPORTS inD =

BEGIN


AnswerCommand: PUBLIC PROCEDURE [hp: inD.HousePtr, confirmed: BOOLEAN] =
-- Clears old composed message and initializes a new one to the standard reply. Refreshes
-- display of the composed message.
BEGIN
answerError: BOOLEAN ← FALSE;
mnp: inD.MessageTextNbrPtr = intC.cmTextNbr;
toc: vmD.TOCHandle = intC.tocTextNbr.toc;
answerMessage: vmD.ComposedMessagePtr;
getMessage: vmD.DisplayMessagePtr;
key: CARDINAL ← vmD.WaitForLock[toc];

GetChar: PROCEDURE [index: CARDINAL] RETURNS [CHARACTER] =
{RETURN[vmD.GetMessageChar[getMessage, index]]};

PutBlock: PROCEDURE [block: Answer.Block] =
BEGIN
[] ← vmD.InsertSubstringInMessage
[answerMessage, LOOPHOLE[Inline.LowHalf[block.buffer] - 2, STRING],
0, block.length];
END; -- of PutBlock --

GetPages: PROCEDURE [nPages: CARDINAL] RETURNS [LONG POINTER] =
{RETURN[Storage.Pages[nPages]]};

FreePages: PROCEDURE [p: LONG POINTER] =
{Storage.FreePages[Inline.LowHalf[p]]};

answerBody: STRING ="M̌essage¿

"L;

-- main body of AnswerCommand

IF tsD.TOCSelectionEmpty[toc, key] THEN
{exD.DisplayException[exD.cantAnswer]; vmD.UnlockTOC[toc, key]; RETURN};

IF ~confirmed AND intC.composedMessageEdited
AND vmD.GetMessageSize[mnp.message] # 0
AND ~inD.AskUserToConfirm[exD.willReplaceMessage] THEN
{vmD.UnlockTOC[toc, key]; RETURN};

getMessage ← vmD.AllocateDisplayMessageObject[];
[] ← vmD.LoadDisplayMessage[toc, key, tsD.FirstSelectedEntry[toc, key], getMessage];

Editor.SwapMessageWithDeletionBuffer[mnp];
Editor.ResetInsertionBuffer[mnp];
answerMessage ← vmD.ComposedMessage[mnp.message];

vmD.InitComposedMessage[answerMessage, ""L];
vmD.StartMessageInsertion[answerMessage, 0];

answerError ← Answer.MakeHeader
[getChar: GetChar,
getLength: vmD.GetMessageSize[getMessage],
putBlock: PutBlock,
getPages: GetPages,
freePages: FreePages,
userName: intC.user.name,
userRegistry: intC.user.registry,
cForCopies: intC.cForCopies];
vmD.FlushDisplayMessage[getMessage, key];
vmD.UnlockTOC[toc, key];
vmD.FreeVirtualMessageObject[getMessage];

[] ← vmD.InsertSubstringInMessage[answerMessage, answerBody, 0, answerBody.length];
vmD.StopMessageInsertion[answerMessage];

-- Answer form complete: make Editor and Interactor happy
BEGIN OPEN inD, Editor;
newMessageLength: CharIndex ← vmD.GetMessageSize[answerMessage];
intC.source ← TextSelection[mnp, 0, 0, 0, 0, char, FALSE];
intC.actionPoint ← 0;
intC.commandType ← get;
intC.target ← TextSelection[mnp: mnp, start: newMessageLength - 11,
end: newMessageLength - 2, point: newMessageLength - 11, key: 0,
mode: char, pendingDelete: intC.editorType = modeless];
intC.newTargetSelection ← TRUE;
intC.pendingDeleteSetByControl ← FALSE;
answerMessage.formatStart ← answerMessage.formatEnd ← 0;
mnp.haveMessage ← TRUE;
intC.composedMessageEdited ← FALSE;
intC.runCommandMode ← FALSE;
IF mnp.protectedFieldPtr # NIL THEN prD.UnprotectAllFields[@mnp.protectedFieldPtr];
RefreshSoThatFirstCharStartsLine[firstChar: 0, firstLine: mnp.lines, mnp: mnp];
intC.deliverCommandHouse.text.length ← 0;
intC.deliverCommandHouse.typeface ← italicFace;
intC.deliverCommandHouse.callable ← FALSE;
IF intC.deliverCommandVisible THEN TextHouseRefresher[intC.deliverCommandHouse];
IF answerError THEN exD.DisplayException[exD.answerIncomplete];
END; -- of OPEN --
END;
-- of AnswerCommand --


END. -- IntAnswerCom --