-- File: WalnutVoiceImpl.mesa
-- Contents: operations for dealing with voice in Walnut messages

-- created September 26, 1983 by Willie-Sue
-- Last edit by:
-- Willie-Sue on: December 29, 1983 2:33 pm

DIRECTORY
Nuthatch USING [NuthatchUserHandle, MakeInterestEntry, RemoveInterestEntry],
PrincOpsUtils USING [IsBound],
Rope,
ViewerClasses USING [Viewer],
ViewerOps USING [AddProp],
Walnuthatch USING [MoveTo, InitializeWalnuthatch],
WalnutSendOps USING [userRName],
WalnutVoice;

WalnutVoiceImpl: CEDAR PROGRAM
IMPORTS
Nuthatch, PrincOpsUtils, ViewerOps, Walnuthatch, WalnutSendOps
EXPORTS WalnutVoice =

BEGIN

ROPE: TYPE = Rope.ROPE;
Viewer: TYPE = ViewerClasses.Viewer;

-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
nuthatchHandle: Nuthatch.NuthatchUserHandle← NIL;
nuthatchTries: INTEGER← 0;

CheckForWalnuthatch: PUBLIC PROC RETURNS[ra: REF ANY] =
-- checks if the Nuthatch stuff is loaded and started; if loaded but there is no nuthatchUserHandle, then the initialization proc is called
-- returns NIL if no Nuthatch or the initialization returned NIL
BEGIN
 success: BOOL;
IF nuthatchHandle # NIL THEN RETURN[nuthatchHandle];
TRUSTED {IF ~PrincOpsUtils.IsBound[Walnuthatch.InitializeWalnuthatch] THEN RETURN[NIL]};
IF nuthatchTries > 5 THEN RETURN[NIL];
 [success, nuthatchHandle]←
   Walnuthatch.InitializeWalnuthatch[WalnutSendOps.userRName !
     ABORTED => CONTINUE];
IF ~success THEN nuthatchTries← nuthatchTries + 1;
RETURN[nuthatchHandle];
END;

InternalCheck: PROC RETURNS[Nuthatch.NuthatchUserHandle] =
-- checks if the Nuthatch stuff is loaded and started; if loaded but there is no nuthatchUserHandle, then the initialization proc is called
-- returns NIL if no Nuthatch or the initialization returned NIL
BEGIN
 success: BOOL← FALSE;
IF nuthatchHandle # NIL THEN RETURN[nuthatchHandle];
TRUSTED {IF ~PrincOpsUtils.IsBound[Walnuthatch.InitializeWalnuthatch] THEN RETURN[NIL]};
DO
IF nuthatchTries > 5 THEN RETURN[NIL];
  [success, nuthatchHandle]←
   Walnuthatch.InitializeWalnuthatch[WalnutSendOps.userRName !
     ABORTED => CONTINUE];
IF success THEN RETURN[nuthatchHandle];
  nuthatchTries← nuthatchTries + 1;
ENDLOOP;
END;

AddNuthatchHandleToViewer: PUBLIC PROC[v: Viewer] =
BEGIN
 nuh: Nuthatch.NuthatchUserHandle← InternalCheck[];
IF nuh # NIL THEN ViewerOps.AddProp[v, $NuthatchHandle, nuh];
END;

MakeInterestEntry: PUBLIC PROC[voiceID, gvID: ROPE] =
BEGIN
 nuh: Nuthatch.NuthatchUserHandle← InternalCheck[];
IF nuh # NIL THEN
  Nuthatch.MakeInterestEntry[nuh, voiceID, gvID ! ABORTED => CONTINUE]
END;

VoiceMoveTo: PUBLIC PROC[msgSetName, msgName: ROPE] =
BEGIN
 nuh: Nuthatch.NuthatchUserHandle← InternalCheck[];
IF nuh # NIL THEN
  Walnuthatch.MoveTo[msgSetName, nuh, msgName ! ABORTED => CONTINUE];
END;

RemoveInterestEntry: PUBLIC PROC[voiceID, gvID: ROPE] =
BEGIN
 nuh: Nuthatch.NuthatchUserHandle← InternalCheck[];
IF nuh # NIL THEN
  Nuthatch.RemoveInterestEntry[nuh, voiceID, gvID ! ABORTED => CONTINUE];
END;

-- * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *

END.