(FILECREATED "11-Jun-87 16:48:56" {QV}<NOTECARDS>1.3K>NEXT>NCBROWSERCARD.;60 221961 

      changes to:  (FNS NC.DelReferencesToCardFromBrowser)

      previous date: " 8-Jun-87 18:24:19" {QV}<NOTECARDS>1.3K>NEXT>NCBROWSERCARD.;59)


(* Copyright (c) 1985, 1986, 1987 by Xerox Corporation. All rights reserved.)

(PRETTYCOMPRINT NCBROWSERCARDCOMS)

(RPAQQ NCBROWSERCARDCOMS ((* * Stuff for the Notecards browser.)
	[DECLARE: COPY FIRST (P (NC.LoadFileFromDirectories (QUOTE NCGRAPHCARD]
	(GLOBALVARS NC.SelectingBrowserSourceMenu NC.SpecialBrowserSpecsFlg 
		    NC.BrowserContentsLinkLabel NC.SubBoxLinkLabel NC.FiledCardLinkLabel 
		    NC.SelectingCardMenu NC.DashingStyles NC.GraphFlowerLinkSeparation 
		    NC.LinkDashingInBrowser NC.ArrowHeadsInBrowser NC.BrowserSpecsStylesheet 
		    NC.BrowserFormatOptions NC.*Graph*BrowserFormat NC.GraphEditMenuItems 
		    NC.GraphEditUnfixedMenuItems NC.LinkIconShowTitleFlg NC.LinkIconShowLinkTypeFlg 
		    NC.LinkIconAttachBitmapFlg NC.BrowserHashArraySize 
		    NC.UseDeletedLinkIconIndicatorsFlg)
	(INITVARS (NC.LinkDashingInBrowser NIL)
		  (NC.ArrowHeadsInBrowser (QUOTE None))
		  (NC.BrowserHashArraySize 2000))
	[VARS [NC.DashingStyles (QUOTE (NIL (4 4)
					    (10 4 2 4)
					    (1 4)
					    (4 10)
					    (8 4)
					    (14 4)
					    (10 4 2 4 2 4)
					    (10 4 2 4 2 4 2 4]
	      (NC.GraphFlowerLinkSeparation 8)
	      (NC.BrowserSpecsStylesheet (CREATE.STYLE (QUOTE ITEMS)
						       (LIST (create MENU ITEMS ← T)
							     (create MENU ITEMS ← T)
							     (create MENU ITEMS ← T)
							     (create MENU ITEMS ← T)
							     (create MENU ITEMS ← T))
						       (QUOTE SELECTIONS)
						       (QUOTE (T T T T T))
						       (QUOTE ITEM.TITLES)
						       (QUOTE (Forward% Links Backward% Links Depth 
									      Format Orientation))
						       (QUOTE ITEM.TITLE.FONT)
						       (FONTCOPY MENUFONT (QUOTE WEIGHT)
								 (QUOTE BOLD))
						       (QUOTE NEED.NOT.FILL.IN)
						       (QUOTE (MULTI MULTI NIL NIL NIL))
						       (QUOTE TITLE)
						       "Browser Specs?"))
	      [NC.BrowserFormatOptions (QUOTE ((*GRAPH* *GRAPH* 
						     "Build a directed graph (no virtual nodes).")
					       (LATTICE LATTICE 
			"Build an acyclic directed graph (uses virtual nodes in case of cycles).")
					       (COMPACT COMPACT 
						     "Build a forest using minimal screen space.")
					       (FAST FAST 
					    "Build a forest, sacrificing screen space for speed."]
	      (NC.*Graph*BrowserFormat (QUOTE *GRAPH*))
	      [NC.GraphEditMenuItems (QUOTE ((Create% Card% &% Node NC.BrowserCreateCardFn 
					    "Create a new card and a corresponding browser node.")
					     (Create% Link% &% Edge NC.BrowserCreateLinkFn 
					    "Create a new link and a corresponding browser edge."
								    (SUBITEMS (
Create% Global% Link% &% Edge NC.BrowserCreateGlobalLinkFn 
			      "Create a new global link and a corresponding browser edge.")))
					     (Delete% Card% &% Node NC.BrowserDeleteCardFn 
						  "Delete an existing card and its browser node.")
					     (Delete% Link% &% Edge NC.BrowserDeleteLinkFn 
						  "Delete an existing link and its browser edge.")
					     (Add% Label NC.BrowserAddLabelFn 
							 "Add a string label to graph.")
					     (Add% Node NC.BrowserAddNodeFn 
				 "Add a node to the browser corresponding to some existing card.")
					     (Add% Edge NC.BrowserAddEdgeFn 
						  "Add an edge to the browser (no link created).")
					     (Remove% Node NC.BrowserRemoveNodeFn 
						       "Remove a browser node (no card deleted).")
					     (Remove% Edge NC.BrowserRemoveEdgeFn 
					     "Remove an edge from the browser (no link deleted).")
					     (Move% Node NC.BrowserMoveNodeFn "Move a browser node."
							 (SUBITEMS (Move% Single% Node 
									     NC.BrowserMoveNodeFn 
									   "Move a browser node.")
								   (Move% Node% &% Subtree 
									  NC.BrowserMoveSubtreeFn 
				    "Move a subtree of nodes following the movement of the root.")
								   (Move% Region 
								    NC.BrowserMoveNodesInRegionFn 
				    "Move all nodes within a specified region to another region.")))
					     (Label% Smaller NC.BrowserShrinkLabelFn 
							  "Reduce font size for a browser label.")
					     (Label% Larger NC.BrowserGrowLabelFn 
							"Increase font size for a browser label.")
					     ("<-> Shade" EDITTOGGLELABEL 
					       "Inverts label shade for a browser label."]
	      (NC.GraphEditUnfixedMenuItems (APPEND NC.GraphEditMenuItems (QUOTE ((FIX% MENU 
								     NC.BrowserFixGraphEditMenuFn 
						    "Attach this menu to edge of browser window."]
	(* * BROWSER mechanisms)
	(FNS NC.MakeBrowserCard NC.BringUpBrowserCard)
	(FNS NC.GrowLinkLattice NC.UpdateBrowserCard NC.RelayoutBrowserCard NC.LayoutNewBrowserNodes 
	     NC.ConnectNodesInBrowser NC.UnconnectNodesInBrowser NC.ExpandBrowserNode 
	     NC.AskBrowserSpecs NC.ChangeBrowserSpecs NC.AskSpecialBrowserSpecs NC.BrowserFlipRoots 
	     NC.SelectGraphNode NC.DisplayGraphLinksBetween NC.RebuildFromNodesInGraph 
	     NC.RemoveDuplicateNodesFromGraph NC.ShowBrowserGraph)
	(RECORDS SPECIALBROWSERSPECS)
	(* * Graph editor menu functions.)
	(FNS NC.GetGraphEditMenu NC.BrowserRightButtonFn NC.GraphEditMenuWhenSelectedFn 
	     NC.BrowserCreateCardFn NC.BrowserAddLabelFn NC.BrowserAddNodeFn NC.BrowserCreateLinkFn 
	     NC.BrowserCreateGlobalLinkFn NC.BrowserAddLink NC.BrowserAddGlobalLink 
	     NC.BrowserAddEdgeFn NC.BrowserDeleteCardFn NC.BrowserRemoveNodeFn NC.BrowserDeleteLinkFn 
	     NC.BrowserRemoveEdgeFn NC.BrowserShrinkLabelFn NC.BrowserGrowLabelFn 
	     NC.BrowserMoveNodeFn NC.BrowserMoveNodesInRegionFn NC.BrowserMoveSubtreeFn 
	     NC.BrowserFixGraphEditMenuFn NC.BrowserCreateCard NC.BrowserCreateLink 
	     NC.BrowserDeleteLink NC.BrowserAddNode NC.BrowserAddLabel NC.BrowserAddEdge 
	     NC.BrowserRemoveNode NC.DelBrowserContentsLink NC.BrowserRemoveEdge)
	(* * Grapher hacks for browser)
	(FNS NC.MakeLinksLegend NC.MakeLinksLegendMenu NC.LinksLegendRepaintFn NC.BrowserDrawLinkFn 
	     NC.DrawFlowerLinks NC.DrawFlowerLink NC.LinksLegendReshapeFn NC.DrawArrowHead)
	(* * for making and manipulating the tiny attached shrunken browser window.)
	(INITVARS (NC.BrowserOverviewDefaultWidth 75)
		  (NC.BrowserOverviewDefaultHeight 75)
		  (NC.LeastScaleForGraphNodeShrinking .3))
	(GLOBALVARS NC.BrowserOverviewDefaultWidth NC.BrowserOverviewDefaultHeight 
		    NC.LeastScaleForGraphNodeShrinking NC.BrowserOverviewSpecsStylesheet 
		    NC.DefaultWhereToAttachOverviewWin NC.DefaultBrowserOverviewMode 
		    NC.OverviewWinMode.Compress NC.OverviewWinMode.Expand)
	(VARS (NC.OverviewWinMode.Compress (QUOTE Compress% Overview% Win))
	      (NC.OverviewWinMode.Expand (QUOTE Expand% Overview))
	      (NC.DefaultBrowserOverviewMode (QUOTE Neither)))
	[INITVARS (NC.DefaultWhereToAttachOverviewWin (QUOTE (LEFT . TOP)))
		  (NC.BrowserOverviewSpecsStylesheet (CREATE.STYLE
						       (QUOTE TITLE)
						       "Choose browser overview specs"
						       (QUOTE ITEM.TITLES)
						       (QUOTE (Edge Position% on% Edge Mode))
						       (QUOTE ITEM.TITLE.FONT)
						       (FONTCOPY MENUFONT (QUOTE WEIGHT)
								 (QUOTE BOLD))
						       (QUOTE ITEMS)
						       (LIST [create MENU ITEMS ←
								     (QUOTE ((LEFT LEFT 
								      "Position along left edge.")
									     (TOP TOP 
								       "Position along top edge.")
									     (RIGHT RIGHT 
								     "Position along right edge.")
									     (BOTTOM BOTTOM 
								    "Position along bottom edge."]
							     [create MENU ITEMS ←
								     (QUOTE ((TOP/RIGHT TOP 
							  "Position at top or right end of edge.")
									     (CENTER CENTER 
								    "Position at center of edge.")
									     (BOTTOM/LEFT BOTTOM 
							    "Position at bottom or left of edge."]
							     (create MENU ITEMS ←
								     (QUOTE ((Compress% Overview% Win
									       
									  Compress% Overview% Win 
			     "Compress the overview window to exactly fit the overview contents.")
									     (Expand% Overview 
										 Expand% Overview 
			      "Expand the overview contents to exactly fill the overview window.")
									     (Neither Neither 
			 "Neither expand the overview contents nor compress the overview window."]
	(FNS NC.MakeBrowserOverviewWin NC.AskBrowserOverviewSpecs)
	(FNS NC.DRAWBOX NC.ShrinkGraphToWindow NC.ScaleGraphNode NC.ComputeOverviewScale 
	     NC.RedrawBrowserOverviewWin NC.DrawWireFrameInOverviewWin NC.CompressOverviewWin 
	     NC.ReattachBrowserOverviewWin NC.BrowserScrollFn NC.BrowserReshapeFn 
	     NC.BrowserOverviewWinRepaintFn NC.BrowserOverviewWinReshapeFn 
	     NC.BrowserOverviewWinMINSIZEFn NC.BrowserOverviewWinButtonEventFn NC.BrowserCardQuitFn)
	(* * Miscellaneous)
	(FNS NC.DelReferencesToCardFromBrowser NC.NewBrowserNodeUIDFromOldUID NC.GetBrowserSubstance 
	     NC.ComputeBrowserSavedLinkingInfo NC.ComputeBrowserSavedLinkingInfoForNode)
	(FNS NC.FetchBrowserRootsInfo NC.FetchBrowserLinkLabels NC.FetchBrowserFormat 
	     NC.FetchSpecialBrowserSpecs NC.FetchBrowserDepth NC.FetchBrowserSavedLinkingInfo 
	     NC.FetchBrowserLinksLegend)
	(FNS NC.SetBrowserRootsInfo NC.SetBrowserLinkLabels NC.SetBrowserFormat 
	     NC.SetSpecialBrowserSpecs NC.SetBrowserDepth NC.SetBrowserSavedLinkingInfo 
	     NC.SetBrowserLinksLegend)
	(FNS NC.ReadBrowserRootsInfo NC.ReadBrowserLinkLabels NC.ReadBrowserFormat 
	     NC.ReadSpecialBrowserSpecs NC.ReadBrowserDepth NC.ReadBrowserSavedLinkingInfo 
	     NC.ReadBrowserSavedLinkingInfoForNode NC.ReadBrowserLinksLegend)
	(FNS NC.WriteBrowserRootsInfo NC.WriteBrowserLinkLabels NC.WriteBrowserFormat 
	     NC.WriteSpecialBrowserSpecs NC.WriteBrowserDepth NC.WriteBrowserSavedLinkingInfo 
	     NC.WriteBrowserSavedLinkingInfoForNode NC.WriteBrowserLinksLegend)
	(FNS NC.GraphLinkIconUpdateCheck NC.BrowserRepaintFn NC.CoerceToGraphNodeID 
	     NC.CoerceToGraphNodeIDOrLabel NC.GetBrowserNodeID NC.MakeBrowserNodeUID 
	     NC.GetBrowserHashArray NC.RemoveBrowserNodeHashArrayEntry NC.HashArrayFromBrowserCard 
	     NC.CardFromBrowserNodeID NC.SmashGraphNodeIDProps NC.PutBrowserSubstance 
	     NC.FetchBrowserRoots NC.SetBrowserRoots)
	(FNS NC.GraphNodeIDGetProp NC.GraphNodeIDPutProp NC.GraphNodeIDRemProp)
	(GLOBALVARS NC.ArrowHeadLength NC.ArrowHeadAngle NC.ArrowHeadXVal NC.ArrowHeadYVal)
	[VARS (NC.ArrowHeadLength 7)
	      (NC.ArrowHeadAngle 20)
	      (NC.ArrowHeadXVal (TIMES NC.ArrowHeadLength (COS NC.ArrowHeadAngle)))
	      (NC.ArrowHeadYVal (TIMES NC.ArrowHeadLength (SIN NC.ArrowHeadAngle]
	(* * init)
	(FNS NC.AddBrowserCard)
	(P (NC.AddBrowserCard))
	(FNS NCAddStub.BrowserCard)))
(* * Stuff for the Notecards browser.)

(DECLARE: COPY FIRST 
(NC.LoadFileFromDirectories (QUOTE NCGRAPHCARD))
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.SelectingBrowserSourceMenu NC.SpecialBrowserSpecsFlg NC.BrowserContentsLinkLabel 
	    NC.SubBoxLinkLabel NC.FiledCardLinkLabel NC.SelectingCardMenu NC.DashingStyles 
	    NC.GraphFlowerLinkSeparation NC.LinkDashingInBrowser NC.ArrowHeadsInBrowser 
	    NC.BrowserSpecsStylesheet NC.BrowserFormatOptions NC.*Graph*BrowserFormat 
	    NC.GraphEditMenuItems NC.GraphEditUnfixedMenuItems NC.LinkIconShowTitleFlg 
	    NC.LinkIconShowLinkTypeFlg NC.LinkIconAttachBitmapFlg NC.BrowserHashArraySize 
	    NC.UseDeletedLinkIconIndicatorsFlg)
)

(RPAQ? NC.LinkDashingInBrowser NIL)

(RPAQ? NC.ArrowHeadsInBrowser (QUOTE None))

(RPAQ? NC.BrowserHashArraySize 2000)

(RPAQQ NC.DashingStyles (NIL (4 4)
			       (10 4 2 4)
			       (1 4)
			       (4 10)
			       (8 4)
			       (14 4)
			       (10 4 2 4 2 4)
			       (10 4 2 4 2 4 2 4)))

(RPAQQ NC.GraphFlowerLinkSeparation 8)

(RPAQ NC.BrowserSpecsStylesheet (CREATE.STYLE (QUOTE ITEMS)
						(LIST (create MENU ITEMS ← T)
						      (create MENU ITEMS ← T)
						      (create MENU ITEMS ← T)
						      (create MENU ITEMS ← T)
						      (create MENU ITEMS ← T))
						(QUOTE SELECTIONS)
						(QUOTE (T T T T T))
						(QUOTE ITEM.TITLES)
						(QUOTE (Forward% Links Backward% Links Depth Format 
								       Orientation))
						(QUOTE ITEM.TITLE.FONT)
						(FONTCOPY MENUFONT (QUOTE WEIGHT)
							  (QUOTE BOLD))
						(QUOTE NEED.NOT.FILL.IN)
						(QUOTE (MULTI MULTI NIL NIL NIL))
						(QUOTE TITLE)
						"Browser Specs?"))

(RPAQQ NC.BrowserFormatOptions ((*GRAPH* *GRAPH* "Build a directed graph (no virtual nodes).")
				  (LATTICE LATTICE 
			"Build an acyclic directed graph (uses virtual nodes in case of cycles).")
				  (COMPACT COMPACT "Build a forest using minimal screen space.")
				  (FAST FAST "Build a forest, sacrificing screen space for speed.")))

(RPAQQ NC.*Graph*BrowserFormat *GRAPH*)

(RPAQQ NC.GraphEditMenuItems ((Create% Card% &% Node NC.BrowserCreateCardFn 
					    "Create a new card and a corresponding browser node.")
				(Create% Link% &% Edge NC.BrowserCreateLinkFn 
					    "Create a new link and a corresponding browser edge."
						       (SUBITEMS (Create% Global% Link% &% Edge
								   NC.BrowserCreateGlobalLinkFn 
				     "Create a new global link and a corresponding browser edge.")))
				(Delete% Card% &% Node NC.BrowserDeleteCardFn 
						  "Delete an existing card and its browser node.")
				(Delete% Link% &% Edge NC.BrowserDeleteLinkFn 
						  "Delete an existing link and its browser edge.")
				(Add% Label NC.BrowserAddLabelFn "Add a string label to graph.")
				(Add% Node NC.BrowserAddNodeFn 
				 "Add a node to the browser corresponding to some existing card.")
				(Add% Edge NC.BrowserAddEdgeFn 
					   "Add an edge to the browser (no link created).")
				(Remove% Node NC.BrowserRemoveNodeFn 
					      "Remove a browser node (no card deleted).")
				(Remove% Edge NC.BrowserRemoveEdgeFn 
					     "Remove an edge from the browser (no link deleted).")
				(Move% Node NC.BrowserMoveNodeFn "Move a browser node."
					    (SUBITEMS (Move% Single% Node NC.BrowserMoveNodeFn 
									  "Move a browser node.")
						      (Move% Node% &% Subtree NC.BrowserMoveSubtreeFn 
				    "Move a subtree of nodes following the movement of the root.")
						      (Move% Region NC.BrowserMoveNodesInRegionFn 
				    "Move all nodes within a specified region to another region.")))
				(Label% Smaller NC.BrowserShrinkLabelFn 
						"Reduce font size for a browser label.")
				(Label% Larger NC.BrowserGrowLabelFn 
					       "Increase font size for a browser label.")
				("<-> Shade" EDITTOGGLELABEL 
				  "Inverts label shade for a browser label.")))

(RPAQ NC.GraphEditUnfixedMenuItems [APPEND NC.GraphEditMenuItems (QUOTE ((FIX% MENU 
								     NC.BrowserFixGraphEditMenuFn 
						    "Attach this menu to edge of browser window."])
(* * BROWSER mechanisms)

(DEFINEQ

(NC.MakeBrowserCard
  [LAMBDA (Card Title NoDisplayFlg ParamList)                (* Randy.Gobbel " 2-Apr-87 15:38")

          (* Make a browser card with id Card using root at RootID and the link following predictae specified by Predicate.
	  IF Root and/or ListOfLinkLabels not specified, ask the user.)



          (* * rht 8/3/84: Changed to call NC.AskLinkLabel with its ReverseLinkLabel parameter set to T.)



          (* * fgh 10/2/84 Changed Link Icons to be image objects in NodeLabel of Graph Npodes rather than annotations on 
	  graph nodes.)



          (* * rht 10/19/84: Fixed setting up of browser card's prop list in case NoDisplayFlg is T so we have no Window.
	  Now NC.MakeLinksLegend returns the label pairs.)



          (* * rht 11/27/84: Removed the WINDOWADDPROP call to put NC.GraphCardCloseFn on the CLOSEFN of the window.
	  This causes trouble. NC.QuitCard will get put on by NC.MakeNoteCard and that's enough.)



          (* * rht 1/3/85: Now puts a dummy region of the right size if the NoDisplayFlg is on.)



          (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.)



          (* * rht 2/14/85: Added VerticalFlg and made BrowserSpecs get put on browser's proplist in all cases.)



          (* * rht 4/1/85: Now calls NC.AskBrowserSpecs with additional Don'tAskFlg in case of call from Programmer's 
	  interface.)



          (* * rht 11/17/85: Updated to handle new card and notefile objects.)



          (* * rht 2/7/86: Now gets browser format, etc. via fetch/set fns.)



          (* * rht 5/6/86: Took out call to NC.SetupTitleBarMenu.)



          (* * rht 5/8/86: Added calls to rig title bar properly.)



          (* * rht 7/10/86: Now passes ListOfLinkLabels to NC.AskBrowserSpecs.)



          (* * rht 9/19/86: Mod to above fix. Now calls NC.MakeNewCardWindow a new fn that creates window and hangs Card off 
	  windowprop.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection. Also added GLOBALVARS 
	  statement.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a 
	  standin for a cross file link icon.)



          (* * rg 3/18/87 added NC.CardSelectionOperation wrapper)



          (* * rht 3/20/87: Removed needless call to NC.ActivateCard.)



          (* * rg 4/2/87 changed wrapper to NCP.WithLockedCards and added NC.IfAllCardsFree wrapper)


    (DECLARE (GLOBALVARS NC.SubBoxLinkLabel NC.BrowserContentsLinkLabel NC.SpecialBrowserSpecsFlg 
			     NC.*Graph*BrowserFormat NC.SelectingBrowserSourceMenu))
    (NCP.WithLockedCards (PROG ([RootCards (MKLIST (LISTGET ParamList (QUOTE ROOTCARDS]
				  (ListOfLinkLabels (LISTGET ParamList (QUOTE LINKTYPES)))
				  (BrowserFormat (LISTGET ParamList (QUOTE FORMAT)))
				  (Depth (LISTGET ParamList (QUOTE DEPTH)))
				  (CardType (NC.RetrieveType Card))
				  Lattice RootNodes Window Graph SpecialBrowserSpecs BrowserSpecs 
				  DropVirtualNodesFlg)
			         (NC.IfAllCardsFree
				   (NC.LockListOfCards RootCards "Make Browser Card")
				   [COND
				     ((NULL NoDisplayFlg)
				       (SETQ Window (NC.MakeNewCardWindow Card (OR Title 
										       "Untitled")))
				       (WINDOWADDPROP Window (QUOTE SHRINKFN)
							(FUNCTION NC.GraphCardShrinkFn]
				   [if (NULL RootCards)
				       then (SETQ RootCards
						(if NoDisplayFlg
						    then (LIST NIL)
						  else (NC.SelectNoteCards NIL NIL 
								    NC.SelectingBrowserSourceMenu 
									       Window 
		      "Please shift-select the Cards and/or Boxes the browser should start from."
									       T]
				   (COND
				     ((EQ RootCards (QUOTE DON'T))
				       (NC.DeactivateCard Card)
				       (CLOSEW Window)
				       (RETURN)))
				   (NC.HoldTTYProcess)
				   [SETQ BrowserSpecs (NC.AskBrowserSpecs Window Card 
									      ListOfLinkLabels Depth 
									      BrowserFormat T
									      (if (OR ParamList 
										     NoDisplayFlg)
										  then
										   (QUOTE DONTASK]
				   (COND
				     ((NULL BrowserSpecs)
				       (NC.DeactivateCard Card)
				       (CLOSEW Window)
				       (RETURN)))
				   (SETQ ListOfLinkLabels (CAR BrowserSpecs))
				   (SETQ Depth (CADR BrowserSpecs))
				   (SETQ BrowserFormat (CADDR BrowserSpecs))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
				   (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
				       then (SETQ DropVirtualNodesFlg T))
				   [SETQ SpecialBrowserSpecs (COND
				       (NC.SpecialBrowserSpecsFlg (NC.AskSpecialBrowserSpecs Window)
								  )
				       (T (create SPECIALBROWSERSPECS]
				   (OR NoDisplayFlg (NC.PrintMsg Window T (CHARACTER 13)
								     
						      "Computing browser graph. Please wait. ..."))
                                                             (* Create new browser hash array)
				   (NC.GetBrowserHashArray Card)
                                                             (* Compute lattice breakdth-first starting from 
							     roots.)
				   (SETQ Lattice (NC.GrowLinkLattice RootCards NIL 
									 ListOfLinkLabels Card Depth))
				   (SETQ RootNodes (for RootCard in RootCards
							collect (NC.GetBrowserNodeID Card 
											 RootCard)))
				   (OR NoDisplayFlg (WINDOWPROP Window (QUOTE NoteCardObject)
								    Card))

          (* * Link destination id information stored in NodeLabel field into a LinkIcon for display)


				   (for Node in Lattice bind NodeID eachtime (BLOCK)
				      do [replace (GRAPHNODE NODELABEL) of Node
					      with (LET ((NewLink (NC.MakeLink
								      Window 
								      NC.BrowserContentsLinkLabel
								      (fetch (GRAPHNODE NODELABEL)
									 of Node)
								      Card NIL)))
						          (if NewLink
							      then (NC.MakeLinkIcon NewLink)
							    else (NC.MakeCrossFileLinkIconStandIn
								     (NCP.CardTitle
								       (fetch (GRAPHNODE NODELABEL)
									  of Node]
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
					   (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node))
					   (NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID)
								    (QUOTE TouchedFlg))
					   (NC.GraphNodeIDRemProp (NC.CoerceToGraphNodeID NodeID)
								    (QUOTE VisitedFlg)))
				   (SETQ Graph (if (AND Lattice RootNodes)
						     then (LAYOUTGRAPH Lattice RootNodes
									   (SUBST (QUOTE LATTICE)
										    
									  NC.*Graph*BrowserFormat 
										    BrowserFormat)
									   (fetch (
SPECIALBROWSERSPECS Font) of SpecialBrowserSpecs)
									   (fetch (
SPECIALBROWSERSPECS MotherD) of SpecialBrowserSpecs)
									   (fetch (
SPECIALBROWSERSPECS PersonalD) of SpecialBrowserSpecs)
									   (fetch (
SPECIALBROWSERSPECS FamilyD) of SpecialBrowserSpecs))
						   else (create GRAPH)))
				   (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph 
											  Window 
									      DropVirtualNodesFlg))
				   (OR NoDisplayFlg (NC.PrintMsg Window NIL "Done!"))
				   (NC.SetSubstance Card Graph)
				   (NC.SetBrowserLinkLabels Card (OR ListOfLinkLabels
									 (LIST NC.SubBoxLinkLabel)))
				   (NC.SetBrowserRoots Card RootCards)
				   (NC.SetBrowserFormat Card BrowserFormat)
				   (NC.SetBrowserDepth Card Depth)
				   (NC.SetSpecialBrowserSpecs Card SpecialBrowserSpecs)
				   (COND
				     (NoDisplayFlg (RETURN Card)))
				   (WINDOWPROP Window (QUOTE GRAPH)
						 Graph)
				   (NC.InstallTitleBarLeftMenu Window CardType)
				   (NC.InstallTitleBarMiddleMenu Window CardType)
				   (NC.RelayoutBrowserCard Window)
				   (RETURN Window])

(NC.BringUpBrowserCard
  [LAMBDA (Card Substance Region/Position)                   (* rht: " 6-Feb-87 15:57")

          (* * Given a browser Substance, open a browser window and set it up to be a NoteCard with ID.)



          (* * rht 11/17/84: Now returns window.)



          (* * rht 9/11/85: Now checks for changed link icon display global params.)



          (* * rht 11/17/85: Now handles new card and Notefile objects.)



          (* * rht 2/1/86: Now restores any saved UID user data info stashed on card's prop list.)



          (* * fgh 2/5/86 Added call to NC.ApplySupersFn)



          (* * rht 2/14/86: Now rebuilds browser hash array.)



          (* * rht 2/28/86: Added WINDOWPROP for SCROLLFN and RESHAPEFN.)



          (* * rht 3/2/86: Took out call to NC.FetchBrowserHashArray.)



          (* * rht 4/5/86: Now only replaces graphnodes' TONODES' NODEID and DESTNODEID if they're non-nil.)



          (* * rht 5/5/86: Took out call to NC.SetupTitleBarMenu.)



          (* * rht&pmi 2/6/87: Moved call to NC.GraphLinkIconUpdateCheck in front of call to GraphCard's EditFn so as to 
	  remove "double display" problem.)


    (LET ((GraphNodes (fetch (GRAPH GRAPHNODES) of Substance))
	  Window OldUIDToNewUIDHashArray BrowserSavedLinkingInfo)

          (* * Restore any saved UID user data info stashed on card UID's prop list.)


         [if (SETQ BrowserSavedLinkingInfo (NC.FetchBrowserSavedLinkingInfo Card))
	     then (SETQ OldUIDToNewUIDHashArray (HASHARRAY 100 NIL (FUNCTION NC.MakeHashKey)
								 (FUNCTION NC.SameUIDP)))
		    (for BrowserSavedLinkingInfoForNode in BrowserSavedLinkingInfo
		       eachtime (BLOCK) bind SourceUID when (SETQ SourceUID
								      (
								   NC.NewBrowserNodeUIDFromOldUID
									(CAR 
								   BrowserSavedLinkingInfoForNode)
									GraphNodes 
									OldUIDToNewUIDHashArray))
		       do (for SavedLinkingInfo on (CDR BrowserSavedLinkingInfoForNode)
			       by (CDDR SavedLinkingInfo) eachtime (BLOCK)
			       do (NC.GraphNodeIDPutProp SourceUID (
							       NC.NewBrowserNodeUIDFromOldUID
							       (CAR SavedLinkingInfo)
							       GraphNodes OldUIDToNewUIDHashArray)
							     (CADR SavedLinkingInfo]
         (NC.SetBrowserSavedLinkingInfo Card NIL)

          (* * For each graph node corresponding to a notecard, hang the card object off the node id's prop list.)


         [for GraphNode in GraphNodes bind LinkIcon DestCard eachtime (BLOCK)
	    when (NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE NODELABEL)
							       of GraphNode)))
	    do (NC.GraphNodeIDPutProp (NC.CoerceToGraphNodeID GraphNode)
					  (QUOTE CardObject)
					  (SETQ DestCard (fetch (Link DestinationCard)
							      of (NC.FetchLinkFromLinkIcon 
											 LinkIcon]

          (* * Make a new browser hash array with the new graph node UIDs.)


         (NC.SetUserDataProp Card (QUOTE BrowserHashArray)
			       NIL)
         (NC.GetBrowserHashArray Card Substance)

          (* * For each graph node, fix the NODEID and DESTNODEID fields of each of its TONODES LinkParameters.)


         [for GraphNode in GraphNodes eachtime (BLOCK)
	    do (for ToNode in (fetch (GRAPHNODE TONODES) of GraphNode)
		    bind (ThisNodeID ← (NC.CoerceToGraphNodeID GraphNode)) eachtime (BLOCK)
		    when (EQ (CAR ToNode)
				 LINKPARAMS)
		    do (AND (LISTGET ToNode (QUOTE NODEID))
				(LISTPUT ToNode (QUOTE NODEID)
					   ThisNodeID))
			 (AND (LISTGET ToNode (QUOTE DESTNODEID))
				(LISTPUT ToNode (QUOTE DESTNODEID)
					   (NC.CoerceToGraphNodeID (CADR ToNode]

          (* * Bring up card and mess with its window.)


         (NC.GraphLinkIconUpdateCheck Card NIL Substance T)
         (SETQ Window (NC.ApplySupersFn EditFn Card Substance Region/Position))
         (NC.MakeLinksLegendMenu Window (NC.FetchBrowserLinksLegend Card))
                                                             (* Disable the old-style right button grapher editor 
							     menu.)
         (WINDOWPROP Window (QUOTE RIGHTBUTTONFN)
		       (FUNCTION NC.BrowserRightButtonFn))
         (WINDOWADDPROP Window (QUOTE SHRINKFN)
			  (FUNCTION NC.GraphCardShrinkFn))
         (WINDOWADDPROP Window (QUOTE REPAINTFN)
			  (FUNCTION NC.BrowserRepaintFn)
			  T)
         (WINDOWPROP Window (QUOTE SCROLLFN)
		       (FUNCTION NC.BrowserScrollFn))
         (WINDOWPROP Window (QUOTE RESHAPEFN)
		       (FUNCTION NC.BrowserReshapeFn))

          (* * I have to hang notecard's Card on window now in case REDISPLAYW runs and tries to get Card from window.)


         (WINDOWPROP Window (QUOTE NoteCardObject)
		       Card)                                 (* Check if link icon display global params have 
							     changed since last time card was up.
							     If so, fix graph nodes and redisplay.)
                                                             (* if (NC.GraphLinkIconUpdateCheck Card Window 
							     Substance T) then (REDISPLAYW Window))
     Window])
)
(DEFINEQ

(NC.GrowLinkLattice
  (LAMBDA (RootCardsList CurrentGraph ListOfLinkLabels GraphCard RemainingSearchDepth)
                                                             (* rht: " 6-Jul-86 17:28")

          (* Grow a lattice by following the links from RootID card among ListOfLinkLabels. Lattice will be fed to 
	  LAYOUTGRAPH, so for each note card encountered by following the links just fill in the ID, LABEL and daughter IDs)



          (* * rht 8/3/84: Changed so as to also follow from links if they are present (prefixed by "←") on 
	  ListOfLinkLabels.)



          (* * rht 10/4/84: Now stores the link label on the prop list of the NODEID of the graph under the property name of 
	  the destination ID. This is so that links can be drawn with dashing depending on the link's label.)



          (* * rht 3/8/85: Added RemainingSearchDepth arg to limit the lattice growth to given depth.)



          (* * rht 8/9/85: Changed so that backward links are no longer stored as a separate link type.
	  Rather they're told apart from forward links by being stored on the destination node's prop list.)



          (* * rht 4/4/85: Now first arg can be either a root Card or an existing graphnode. If the latter, then we're 
	  expanding an existing graph below that node. If the former than we're starting a new lattice.)



          (* * rht 10/17/85: Changed from a recursive depth-first algorithm to a loop-driven breadth-first alg.)



          (* * rht 11/17/85: Handles new card and notefile objects.)


    (LET (CardsAndDepthsQueue)                               (* Make the queue contain pairs of root Card and depth
							     remaining to search.)
         (SETQ CardsAndDepthsQueue (for Card in RootCardsList collect (CONS Card 
									     RemainingSearchDepth)))
                                                             (* Make it a TCONC list for fast appending to the 
							     end.)
         (SETQ CardsAndDepthsQueue (CONS CardsAndDepthsQueue (LAST CardsAndDepthsQueue)))

          (* * Do breadth-first search using the queue IDsAndDepthsQueue.)


         (for bind CardAndDepth Card RemainingSearchDepth ToLinks FromLinks DestinationIDs 
		       GraphNodeID GraphNode
	    eachtime (BLOCK)                             (* Grab and take apart 1st pair on queue.)
		       (SETQ CardAndDepth (CAAR CardsAndDepthsQueue))
		       (SETQ Card (CAR CardAndDepth))
		       (SETQ RemainingSearchDepth (CDR CardAndDepth)) 
                                                             (* Remove the front pair from the queue.)
		       (RPLACA CardsAndDepthsQueue (CDAR CardsAndDepthsQueue)) 
                                                             (* If that was the last pair, then start queue over 
							     fresh.)
		       (if (NULL (CAR CardsAndDepthsQueue))
			   then (SETQ CardsAndDepthsQueue NIL))
	    while Card unless (NC.SameCardP Card GraphCard)
	    do (SETQ GraphNodeID (NC.GetBrowserNodeID GraphCard Card)) 
                                                             (* Go grab this ID's links.)
		 (if (NC.ActiveCardP Card)
		     then (SETQ ToLinks (NC.FetchToLinks Card))
			    (SETQ FromLinks (NC.FetchFromLinks Card))
		   else (NC.GetLinks Card)
			  (SETQ ToLinks (NC.FetchToLinks Card))
			  (SETQ FromLinks (NC.FetchFromLinks Card)))
		 (if (IGREATERP RemainingSearchDepth 0)
		     then                                  (* Crush the ID's proplist.)
			    (if (NOT (NC.GraphNodeIDGetProp GraphNodeID (QUOTE TouchedFlg)))
				then (NC.SmashGraphNodeIDProps GraphNodeID)
				       (NC.GraphNodeIDPutProp GraphNodeID (QUOTE TouchedFlg)
								T))
			    (SETQ DestinationIDs
			      (NCONC (for Link in ToLinks bind DestID DestVisitedFlg 
								       DestTouchedFlg ThisWayLinkFlg 
								       OtherWayLinkFlg
					  eachtime (BLOCK)
						     (SETQ DestID (NC.GetBrowserNodeID
							 GraphCard
							 (fetch (Link DestinationCard)
							    of Link)))
						     (SETQ DestVisitedFlg (NC.GraphNodeIDGetProp
							 DestID
							 (QUOTE VisitedFlg)))
						     (SETQ DestTouchedFlg (NC.GraphNodeIDGetProp
							 DestID
							 (QUOTE TouchedFlg)))
						     (SETQ ThisWayLinkFlg (NC.LinkLabelP Link 
										 ListOfLinkLabels))
						     (SETQ OtherWayLinkFlg (NC.ReverseLinkLabelP
							 Link ListOfLinkLabels))
					  when ThisWayLinkFlg unless (AND DestVisitedFlg 
										OtherWayLinkFlg)
					  collect          (* Record presence of this link.)
						    (NC.UIDAddProp GraphNodeID DestID
								     (fetch (Link Label)
									of Link)
								     T)
						    DestID)
				       (for Link in FromLinks
					  bind DestID DestTouchedFlg DestVisitedFlg ThisWayLinkFlg 
						 OtherWayLinkFlg SourceCard
					  eachtime (BLOCK)
						     (if (NOT (NC.SameCardP
								    GraphCard
								    (SETQ SourceCard
								      (fetch (Link SourceCard)
									 of Link))))
							 then (SETQ DestID (NC.GetBrowserNodeID
								    GraphCard SourceCard))
								(SETQ DestVisitedFlg
								  (NC.GraphNodeIDGetProp
								    DestID
								    (QUOTE VisitedFlg)))
								(SETQ DestTouchedFlg
								  (NC.GraphNodeIDGetProp
								    DestID
								    (QUOTE TouchedFlg)))
								(SETQ ThisWayLinkFlg
								  (NC.ReverseLinkLabelP Link 
										 ListOfLinkLabels))
								(SETQ OtherWayLinkFlg
								  (NC.LinkLabelP Link 
										 ListOfLinkLabels)))
					  when ThisWayLinkFlg unless (AND DestVisitedFlg 
										OtherWayLinkFlg)
					  collect 

          (* Crush the dest node's prop list if it's never been touched. But if dest node is a fringe node for this search, 
	  don't have to clear the whole proplist.)


						    (if (NOT DestTouchedFlg)
							then (if (EQ 1 RemainingSearchDepth)
								   then (NC.GraphNodeIDRemProp
									    DestID GraphNodeID)
								 else (NC.SmashGraphNodeIDProps
									  DestID)
									(NC.GraphNodeIDPutProp
									  DestID
									  (QUOTE TouchedFlg)
									  T)))
                                                             (* Record presence of this link.)
						    (NC.UIDAddProp DestID GraphNodeID
								     (fetch (Link Label)
									of Link)
								     T)
						    DestID)))
			    (SETQ DestinationIDs (DREMOVE (NC.GetBrowserNodeID GraphCard 
										     GraphCard)
							      (INTERSECTION DestinationIDs 
									      DestinationIDs)))
		   else (SETQ DestinationIDs NIL))
		 (NC.GraphNodeIDPutProp GraphNodeID (QUOTE VisitedFlg)
					  T)

          (* * Create new node and add to graph unless we're working on a node already in the graph.)


		 (if (SETQ GraphNode (FASSOC GraphNodeID CurrentGraph))
		     then                                  (* If node is in graph, but we won't expand further, 
							     then leave it's destination IDs alone.)
			    (AND (GREATERP RemainingSearchDepth 0)
				   (replace (GRAPHNODE TONODES) of GraphNode with 
										   DestinationIDs))
		   else (SETQ CurrentGraph
			    (NCONC CurrentGraph
				     (LIST (create GRAPHNODE
						       NODEID ← GraphNodeID
						       TONODES ← DestinationIDs
						       NODELABEL ← Card)))))

          (* * Attach new IDs to end of queue.)


		 (for DestinationID in DestinationIDs bind DestCard
		    eachtime (BLOCK)
			       (SETQ DestCard (NC.CardFromBrowserNodeID DestinationID))
		    unless (OR (NC.GraphNodeIDGetProp DestinationID (QUOTE VisitedFlg))
				   (for CardAndDepth in (CAR CardsAndDepthsQueue)
				      eachtime (BLOCK) thereis (NC.SameCardP DestCard
										     (CAR 
										     CardAndDepth))))
		    do (SETQ CardsAndDepthsQueue (TCONC CardsAndDepthsQueue
							      (CONS DestCard (SUB1 
									     RemainingSearchDepth)))))
	   )
     CurrentGraph)))

(NC.UpdateBrowserCard
  [LAMBDA (Window)                                           (* Randy.Gobbel " 2-Apr-87 15:38")

          (* * rht 10/14/84: Added call to DETACHALLWINDOWS to close any existing links legend window and prompt window.
	  Also added call to NC.MakeLinksLegend to make a new attached legend menu.)



          (* * rht 1/15/85: Put hooks for AddNode, AddLink, etc. so editing graph edits underlying structure.)



          (* * rht 2/14/85: Added ability to respecify roots and link labels before recomputing graph.)



          (* * rht 3/8/85: Modified to use new browser props stored on card's proplist as of release 1.2.)



          (* * rht 3/17/85: Now takes OnlyLayoutFlg argument. If set, then don't recompute lattice or ask about root nodes.)



          (* * rht 11/17/85: updated to handle new card and notefile objects.)



          (* * kirk 23Jan86 Changed to use NC.AskYesOrNo)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.)



          (* * rht 3/7/86: Now only closes the Links legend menu attached window.)



          (* * rht 6/10/86: Moved code to delete links legend menu and code to make new browser hash array to after 
	  questioning user about respecifying roots.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rht 12/16/86: Now checks that NC.MakeLink succeeded before creating a real link icon. If not, then make a 
	  standin for a cross file link icon.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)



          (* * rg 3/18/87 added NC.CardSelectionOperation wrapper)



          (* * rht 3/19/87: Fixed the part that calls NC.MakeLink so it really only rebuilds links if they've changed.)



          (* * rg 4/1/87 changed CANCELLED to DON'T)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Recompute Browser Card" NIL
	   (NCP.WithLockedCards
	     (PROG (LinkLabels RootCards RootNodes Lattice LinkIcon Graph GraphNodes NodeLabel 
				 BrowserSpecs BrowserFormat DropVirtualNodesFlg Depth 
				 SpecialBrowserSpecs OldLabelNodes OldRootCards)
		     (SETQ RootCards (NC.FetchBrowserRoots Card))
		     (NC.IfAllCardsFree
		       (NC.LockListOfCards RootCards "Update Browser Card")
		       (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
		       [SETQ BrowserFormat (OR (NC.FetchBrowserFormat Card)
						   (QUOTE (LATTICE]
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
		       (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
			   then (SETQ DropVirtualNodesFlg T))
		       (SETQ Depth (OR (NC.FetchBrowserDepth Card)
					   999999))
		       (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card)
							 (create SPECIALBROWSERSPECS)))
		       [SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									     (WINDOWPROP
									       Window
									       (QUOTE GRAPH]
                                                             (* Get new roots.)
		       [if (OR (NULL RootCards)
				   (NC.AskYesOrNo "Want to respecify roots? " "--" "No" T Window T 
						    NIL))
			   then (NC.BrowserFlipRoots Window Card GraphNodes (SETQ OldRootCards 
							   RootCards))
				  (SETQ RootCards (NC.SelectNoteCards NIL NIL 
								    NC.SelectingBrowserSourceMenu 
									  Window (CONCAT
									    
		      "Please shift-select the Cards and/or Boxes the browser should start from."
									    (CHARACTER 13)
									    
							       "(Current roots are highlighted.)")
									  T))
				  (NC.BrowserFlipRoots Window Card GraphNodes OldRootCards)
				  (COND
				    ((EQ RootCards (QUOTE DON'T))
				      (RETURN]             (* Get rid of the links legend menu attached window.)
		       (for Win in (ATTACHEDWINDOWS Window) when (WINDOWPROP Win
										       (QUOTE
											 
										  LINKSLEGENDWINP))
			  do (DETACHWINDOW Win)
			       (CLOSEW Win))               (* Smash the current hash array, putting a fresh one 
							     in its place.)
		       (NC.GetBrowserHashArray Card)
		       (NC.PrintMsg Window T (CHARACTER 13)
				      "Computing browser graph. Please wait. ...")
                                                             (* Compute lattice breadth-first from the roots.)
		       (SETQ Lattice (NC.GrowLinkLattice RootCards NIL LinkLabels Card Depth))
		       (SETQ RootNodes (for RootCard in RootCards collect (
									      NC.GetBrowserNodeID
										    Card RootCard)))
		       (NC.SetPropListDirtyFlg Card T)     (* Remove all links that are in the old browser graph 
							     but not in the new one)
		       [for Node in GraphNodes eachtime (BLOCK)
			  unless [for LatticeNode in Lattice bind (CardForNode
									    ←
									    (
									 NC.CardFromBrowserNodeID
									      (
									   NC.CoerceToGraphNodeID
										Node)))
				      thereis (NC.SameCardP CardForNode (
								  NC.CardFromBrowserNodeID
								  (NC.CoerceToGraphNodeID 
										      LatticeNode]
			  do (LET ((NodeLabel (fetch (GRAPHNODE NODELABEL) of Node)))
				    (COND
				      ((NC.LinkIconImageObjP NodeLabel)
					(NC.DeleteLink (NC.FetchLinkFromLinkIcon NodeLabel)
							 T T))
				      ((STRINGP NodeLabel)
                                                             (* Collect the label nodes from the old browser.)
					(SETQ OldLabelNodes (CONS Node OldLabelNodes]
                                                             (* Create Links for all nodes in the new browser graph
							     but not in the old one.)
		       [for Node in Lattice eachtime (BLOCK)
			  do (LET [(NodeID (fetch (GRAPHNODE NODEID) of Node))
				     (OldNode (for GraphNode in GraphNodes
						 bind (CardForNode ← (NC.CardFromBrowserNodeID
								       (NC.CoerceToGraphNodeID
									 Node)))
						 when (NC.SameCardP CardForNode
									(NC.CardFromBrowserNodeID
									  (NC.CoerceToGraphNodeID
									    GraphNode)))
						 do (RETURN GraphNode]
				    [if OldNode
					then (replace (GRAPHNODE NODELABEL) of Node
						  with (fetch (GRAPHNODE NODELABEL) of OldNode))
				      else (replace (GRAPHNODE NODELABEL) of Node
						with
						 (LET ((NewLink (NC.MakeLink Window 
								      NC.BrowserContentsLinkLabel
									       (fetch (GRAPHNODE
											  NODELABEL)
										  of Node)
									       Card NIL)))
						      (if NewLink
							  then (NC.MakeLinkIcon NewLink)
							else (NC.MakeCrossFileLinkIconStandIn
								 (NCP.CardTitle
								   (fetch (GRAPHNODE NODELABEL)
								      of Node]
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
				    (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg))
				    (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg]
                                                             (* Throw in the label nodes from the old browser.)
		       (SETQ Lattice (NCONC Lattice OldLabelNodes))
                                                             (* For each old label node, take away nonexistent 
							     fromnodes and save the label nodes that no longer have
							     any from nodes.)
		       (for OldLabelNode in OldLabelNodes eachtime (BLOCK)
			  do (replace (GRAPHNODE FROMNODES) of OldLabelNode
				  with (for FromNodeID in (fetch (GRAPHNODE FROMNODES)
								   of OldLabelNode)
					    bind FromNode eachtime (BLOCK)
					    when (SETQ FromNode (FASSOC FromNodeID Lattice))
					    collect        (* If the From node isn't a label node, then add to 
							     its Tonode list.)
						      [if (NC.LinkIconImageObjP
							      (fetch (GRAPHNODE NODELABEL)
								 of FromNode))
							  then (replace (GRAPHNODE TONODES)
								    of FromNode
								    with
								     (CONS (fetch (GRAPHNODE
											NODEID)
										of OldLabelNode)
									     (fetch (GRAPHNODE
											TONODES)
										of FromNode]
						      FromNodeID))
                                                             (* For the old label node's ToNodes, just need to 
							     remove any for ToNodes that no longer exist.)
			       (replace (GRAPHNODE TONODES) of OldLabelNode
				  with (for ToNodeID in (fetch (GRAPHNODE TONODES)
								 of OldLabelNode)
					    bind ToNode eachtime (BLOCK)
					    when (SETQ ToNode (FASSOC ToNodeID Lattice))
					    collect        (* If the To node isn't a label node, then add to its 
							     FromNode list.)
						      [if (NC.LinkIconImageObjP
							      (fetch (GRAPHNODE NODELABEL)
								 of ToNode))
							  then (replace (GRAPHNODE FROMNODES)
								    of ToNode
								    with
								     (CONS (fetch (GRAPHNODE
											NODEID)
										of OldLabelNode)
									     (fetch (GRAPHNODE
											FROMNODES)
										of ToNode]
						      ToNodeID)))
                                                             (* Layout graph, including as roots any non-virtual 
							     nodes with no from nodes to avoid disconnected 
							     graphs.)
		       (SETQ Graph (if (AND Lattice RootNodes)
					 then (LAYOUTGRAPH
						  Lattice
						  (for Node in Lattice bind NodeID
						     eachtime (BLOCK)
								(SETQ NodeID
								  (OR (NC.CoerceToGraphNodeID
									  Node)
									(fetch (GRAPHNODE NODEID)
									   of Node)))
						     when (OR (FMEMB NodeID RootNodes)
								  (NULL (fetch (GRAPHNODE 
											FROMNODES)
									     of Node)))
						     collect NodeID)
						  (SUBST (QUOTE LATTICE)
							   NC.*Graph*BrowserFormat BrowserFormat)
						  (fetch (SPECIALBROWSERSPECS Font) of 
									      SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS MotherD)
						     of SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS PersonalD)
						     of SpecialBrowserSpecs)
						  (fetch (SPECIALBROWSERSPECS FamilyD)
						     of SpecialBrowserSpecs))
				       else (create GRAPH)))
                                                             (* Build links legend and fix up TONODES in the 
							     graph.)
		       (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									      DropVirtualNodesFlg))
		       (NC.SetBrowserRoots Card RootCards)
		       (NC.SetBrowserDepth Card Depth)
		       (WINDOWPROP Window (QUOTE GRAPH)
				     Graph)
		       (NC.RelayoutBrowserCard Window])

(NC.RelayoutBrowserCard
  [LAMBDA (Window)                                           (* rht: "13-May-87 10:54")

          (* * Called from the middle button of a browser or structeditbrowser card. This lays out and displays the browser, 
	  but does not recompute the nodes.)



          (* * rht 11/17/85: updated to handle new notefile and card objects.)



          (* * rht 2/7/86: Now gets browser format, etc. via fetch/set fns.)



          (* * rht 2/28/86: Added WINDOWPROP for SCROLLFN and RESHAPEFN.)



          (* * rht 5/8/86: Added calls to rig title bar properly.)



          (* * fgh 6/30/86 Added NC.GRAPHERCOPYBUTTONEVENTFN to SHOWGRAPH call)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Relayout Browser Card" NIL
	   (PROG (RootCards RootNodeIDs OldToNodePairs Graph GraphNodes BrowserFormat 
			      DropVirtualNodesFlg SpecialBrowserSpecs)
	           (NC.PrintMsg Window T "Laying out graph ...")
	           (SETQ RootCards (NC.FetchBrowserRoots Card))
	           [SETQ BrowserFormat (OR (NC.FetchBrowserFormat Card)
					       (QUOTE (LATTICE]
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
	           (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		       then (SETQ DropVirtualNodesFlg T))
	           (SETQ SpecialBrowserSpecs (OR (CAR (NC.FetchSpecialBrowserSpecs Card))
						     (create SPECIALBROWSERSPECS)))
	           [SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH]
                                                             (* Create hash array if haven't already.)
	           (NC.GetBrowserHashArray Card Graph)     (* check graph node size against image box size.)
	           (NC.GraphLinkIconUpdateCheck Card Window Graph NIL)

          (* Save the TONODES values of the nodes so can replace later after LAYOUTGRAPH call. At the same time, throw away 
	  all the link params info in TONODES field.)


	           [SETQ OldToNodePairs (for Node in GraphNodes bind ToNodes eachtime
										      (BLOCK)
					     collect
					      (PROG1 [CONS (fetch (GRAPHNODE NODEID)
								  of Node)
							       (APPEND (SETQ ToNodes
									   (fetch (GRAPHNODE 
											  TONODES)
									      of Node]
						       (replace (GRAPHNODE TONODES) of Node
							  with (for ToNode in ToNodes
								    collect
								     (if (EQ (CAR ToNode)
										 LINKPARAMS)
									 then (CADR ToNode)
								       else ToNode]
	           (SETQ RootNodeIDs (for RootCard in RootCards collect (NC.GetBrowserNodeID
										  Card RootCard)))
	           (NC.SetPropListDirtyFlg Card T)         (* Layout graph, including as roots any non-virtual 
							     nodes with no from nodes to avoid disconnected 
							     graphs.)
	           (SETQ Graph (if GraphNodes
				     then (LAYOUTGRAPH
					      GraphNodes
					      (for Node in GraphNodes bind NodeID
						 eachtime (BLOCK)
							    (SETQ NodeID (fetch (GRAPHNODE NODEID)
									      of Node))
						 when (OR (AND (NULL (fetch (GRAPHNODE
											FROMNODES)
										of Node))
								     (NOT (LISTP NodeID)))
							      (FMEMB NodeID RootNodeIDs))
						 collect NodeID)
					      (SUBST (QUOTE LATTICE)
						       NC.*Graph*BrowserFormat BrowserFormat)
					      (fetch (SPECIALBROWSERSPECS Font) of 
									      SpecialBrowserSpecs)
					      (fetch (SPECIALBROWSERSPECS MotherD) of 
									      SpecialBrowserSpecs)
					      (fetch (SPECIALBROWSERSPECS PersonalD) of 
									      SpecialBrowserSpecs)
					      (fetch (SPECIALBROWSERSPECS FamilyD) of 
									      SpecialBrowserSpecs))
				   else (create GRAPH)))

          (* Replace the TONODES fields of the Graph nodes by their pre-LAYOUTGRAPH values. Also throw away any nodes that 
	  didn't appear in the old graph.)


	           (if Graph
		       then (replace (GRAPH GRAPHNODES) of Graph
				 with (for Node in (fetch (GRAPH GRAPHNODES) of Graph)
					   bind AssocPair eachtime (BLOCK)
					   when (SETQ AssocPair (FASSOC (fetch (GRAPHNODE
											 NODEID)
										 of Node)
									      OldToNodePairs))
					   collect (replace (GRAPHNODE TONODES) of Node
							with (CDR AssocPair))
						     (if DropVirtualNodesFlg
							 then (replace (GRAPHNODE NODEBORDER)
								   of Node with NIL))
                                                             (* Throw away LINKPARAMS junk from the FromNodes that 
							     LAYOUTGRAPH stuck in.)
						     (replace (GRAPHNODE FROMNODES) of Node
							with (for FromNode
								  in (fetch (GRAPHNODE FROMNODES)
									  of Node)
								  eachtime (BLOCK)
								  collect
								   (if (EQ (CAR FromNode)
									       LINKPARAMS)
								       then (CADR FromNode)
								     else FromNode)))
						     Node)))
	           (SHOWGRAPH Graph Window (FUNCTION NC.GraphCardLeftButtonFn)
				(FUNCTION NC.GraphCardMiddleButtonFn)
				NIL T (FUNCTION NC.GRAPHERCOPYBUTTONEVENTFN))

          (* * Have to reset windowprops since SHOWGRAPH messes with them.)

                                                             (* Disable the old-style right button grapher editor 
							     menu.)
	           (WINDOWPROP Window (QUOTE RIGHTBUTTONFN)
				 (FUNCTION NC.BrowserRightButtonFn))
	           (WINDOWADDPROP Window (QUOTE REPAINTFN)
				    (FUNCTION NC.BrowserRepaintFn)
				    T)
	           (WINDOWPROP Window (QUOTE SCROLLFN)
				 (FUNCTION NC.BrowserScrollFn))
	           (WINDOWPROP Window (QUOTE RESHAPEFN)
				 (FUNCTION NC.BrowserReshapeFn))
	           (NC.SetSubstance Card (WINDOWPROP Window (QUOTE GRAPH)))
	           (NC.MarkCardDirty Card)
	           (NC.InstallTitleBarButtonEventFn Window (FUNCTION NC.TitleBarButtonEventFn))
	           (NC.InstallCopyButtonEventFn Window)
	           (NC.ClearMsg Window T])

(NC.LayoutNewBrowserNodes
  [LAMBDA (RootNode NewNodes BrowserFormat SpecialBrowserSpecs)
                                                             (* rht: " 5-Nov-86 17:41")

          (* * Hold onto old location of RootNode. Then layout the subgraph having root RootNode and lattice NewNodes.
	  Finally, translate the locations of NewNodes using old loc of RootNode.)



          (* * rht 8/21/86: LAYOUTGRAPH destroys FROMNODES of root node. Now we save and restore these after LAYOUTGRAPH is 
	  called.)



          (* * rht 11/5/86: Now replaces ToNodes of each node with a subset consisting only of nodes in NewNodes so 
	  LAYOUTGRAPH won't break. Afterwards, puts the original list back.)


    (DECLARE (GLOBALVARS NC.*Graph*BrowserFormat))
    (LET ((OldRootNodePos (fetch (GRAPHNODE NODEPOSITION) of RootNode))
	  (Lattice (CONS RootNode NewNodes))
	  (FromNodes (fetch (GRAPHNODE FROMNODES) of RootNode))
	  NewRootNodePos)                                    (* Stash old ToNodes and replace with intersection of 
							     original ToNodes and NewNodes.)
         [for Node in Lattice do (LET ((NodeID (NC.CoerceToGraphNodeID Node))
					     (ToNodes (fetch (GRAPHNODE TONODES) of Node)))
					    (NC.GraphNodeIDPutProp NodeID (QUOTE OldToNodes)
								     ToNodes)
					    (replace (GRAPHNODE TONODES) of Node
					       with (for Node in ToNodes
							 when (FASSOC Node Lattice) collect
											 Node]
         (LAYOUTGRAPH Lattice (LIST (fetch (GRAPHNODE NODEID) of RootNode))
			(SUBST (QUOTE LATTICE)
				 NC.*Graph*BrowserFormat BrowserFormat)
			(fetch (SPECIALBROWSERSPECS Font) of SpecialBrowserSpecs)
			(fetch (SPECIALBROWSERSPECS MotherD) of SpecialBrowserSpecs)
			(fetch (SPECIALBROWSERSPECS PersonalD) of SpecialBrowserSpecs)
			(fetch (SPECIALBROWSERSPECS FamilyD) of SpecialBrowserSpecs))
                                                             (* Restore FROMNODES of RootNode.)
         (replace (GRAPHNODE FROMNODES) of RootNode with FromNodes)
         (SETQ NewRootNodePos (fetch (GRAPHNODE NODEPOSITION) of RootNode))
         (for Node in Lattice
	    bind (XOffset ← (DIFFERENCE (fetch XCOORD of OldRootNodePos)
					    (fetch XCOORD of NewRootNodePos)))
		   (YOffset ← (DIFFERENCE (fetch YCOORD of OldRootNodePos)
					    (fetch YCOORD of NewRootNodePos)))
	    do                                             (* Recover old list of ToNodes.)
		 (replace (GRAPHNODE TONODES) of Node with (NC.GraphNodeIDGetProp
								   (NC.CoerceToGraphNodeID Node)
								   (QUOTE OldToNodes)))
		 (LET ((NodePos (fetch (GRAPHNODE NODEPOSITION) of Node)))
		      (replace (GRAPHNODE NODEPOSITION) of Node
			 with (create POSITION
					  XCOORD ← (PLUS XOffset (fetch XCOORD of NodePos))
					  YCOORD ← (PLUS YOffset (fetch YCOORD of NodePos])

(NC.ConnectNodesInBrowser
  [LAMBDA (Window)                                           (* Randy.Gobbel " 4-Mar-87 13:50")

          (* * Draw any links, from the current link set, between any pairs of nodes currently being shown in the browser.)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns. Also fixed one last old call to 
	  GETPROPLIST on a NodeID.)



          (* * rht 3/2/86: Added WINDOWPROP for SCROLLFN and RESHAPEFN.)



          (* * fgh 5/21/86 Updated reinstallation of title bar menus after SHOWGRAPH to use new title bar menu mechanism.)



          (* * rht 6/10/86: Now calls NC.ShowBrowserGraph.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Reconnect Browser Card" NIL
	   (PROG (LinkLabels Graph GraphNodes BrowserFormat DropVirtualNodesFlg NodeIDs)
	           (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
	           (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
	           (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		       then (SETQ DropVirtualNodesFlg T))
	           [SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH]
                                                             (* Create hash array if haven't already.)
	           (NC.GetBrowserHashArray Card Graph)     (* check graph node size against image box size.)
	           (NC.GraphLinkIconUpdateCheck Card Window Graph NIL)
                                                             (* These are the workhorse loops that rebuild the 
							     TONODES of each nonvirtual node.)
                                                             (* First smash all the nodeID's proplists and 
							     accumulate nodeIDs.)
	           (SETQ NodeIDs (for Node in GraphNodes bind NodeID eachtime (BLOCK)
				      when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL)
									of Node))
				      collect (NC.SmashGraphNodeIDProps (SETQ NodeID
									      (
									   NC.CoerceToGraphNodeID
										Node)))
						NodeID))     (* Throw away duplicates obtained from virtual nodes.)
	           (SETQ NodeIDs (INTERSECTION NodeIDs NodeIDs))

          (* Next accumulate all linktypes on the from node's proplist using the To node's graphnodeID as prop name.
	  We do the analogous thing for backward links, but notice that we ignore backward linktypes that also appear in the 
	  list in their forward version.)


	           (for NodeID in NodeIDs bind RealCard
		      do (for Link in (NC.RetrieveToLinks (SETQ RealCard (
								      NC.CardFromBrowserNodeID
								      NodeID)))
			      bind DestNodeID eachtime (BLOCK) when (NC.LinkLabelP Link 
										       LinkLabels)
			      when (FMEMB (SETQ DestNodeID (NC.GetBrowserNodeID
						  Card
						  (fetch (Link DestinationCard) of Link)))
					      NodeIDs)
			      do (NC.UIDAddProp NodeID DestNodeID (fetch (Link Label)
									 of Link)
						    T))
			   (for Link in (NC.RetrieveFromLinks RealCard) bind SourceNodeID
			      eachtime (BLOCK) when (AND (NC.ReverseLinkLabelP Link 
										       LinkLabels)
								 (NOT (NC.LinkLabelP Link 
										       LinkLabels)))
			      when (FMEMB (SETQ SourceNodeID (NC.GetBrowserNodeID
						  Card
						  (fetch (Link SourceCard) of Link)))
					      NodeIDs)
			      do (NC.UIDAddProp SourceNodeID NodeID (fetch (Link Label)
									   of Link)
						    T)))
	           [for Node in GraphNodes bind NodeID OldToNodeIDs eachtime (BLOCK)
		      unless (LISTP (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node)))
		      when (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of Node))
		      do                                   (* Accumulate the old NodeIDs, possibly virtual, from 
							     the TONODES list.)
			   (SETQ OldToNodeIDs (for ToNode in (fetch (GRAPHNODE TONODES)
								      of Node)
						   collect (if (EQ (CAR ToNode)
									 LINKPARAMS)
								 then (CADR ToNode)
							       else ToNode)))

          (* The trick here is to use a virtual node for this ToNode if one was used before, otherwise just the ToNodeID.
	  Also throw in the label nodes that were in the TONODES list before.)


			   (replace (GRAPHNODE TONODES) of Node
			      with (NCONC (for ToNodeID on (
							 NC.ComputeBrowserSavedLinkingInfoForNode
								     NodeID)
						 by (CDDR ToNodeID) eachtime (BLOCK)
						 collect (OR (for OldToNodeID in OldToNodeIDs
								    thereis
								     (AND (LISTP OldToNodeID)
									    (EQ (CAR ToNodeID)
										  (CAR OldToNodeID))
									    OldToNodeID))
								 (CAR ToNodeID)))
					      (for ToNodeID in OldToNodeIDs eachtime (BLOCK)
						 unless (NC.SameCardP Card (
									 NC.CardFromBrowserNodeID
									    (NC.CoerceToGraphNodeID
									      ToNodeID)))
						 collect ToNodeID]
	           (NC.RebuildFromNodesInGraph GraphNodes)
	           (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									  DropVirtualNodesFlg))
                                                             (* Display the graph.)
	           (NC.ShowBrowserGraph Graph Window)
	           (NC.SetSubstance Card (WINDOWPROP Window (QUOTE GRAPH)))
	           (NC.MarkCardDirty Card)
	           (NC.ClearMsg Window T])

(NC.UnconnectNodesInBrowser
  [LAMBDA (Window)                                           (* Randy.Gobbel " 4-Mar-87 13:51")

          (* * Remove all the links in the browser.)



          (* * rht 11/17/85: Now handles new card and notefile objects.)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.)



          (* * fgh 5/21/86 Updated reinstallation of title bar menus after SHOWGRAPH to use new title bar menu mechanism.)



          (* * rht 6/10/86: Now calls NC.ShowBrowserGraph.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation Card "Unconnect Browser Card" NIL
				    (PROG (Graph GraphNodes BrowserFormat DropVirtualNodesFlg)
					    (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
					    (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
						then (SETQ DropVirtualNodesFlg T))
					    [SETQ GraphNodes (fetch (GRAPH GRAPHNODES)
								  of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH]
                                                             (* smash all the nodeID's proplists and TONODES 
							     fields.)
					    (for Node in GraphNodes bind NodeID
					       unless [PROGN (BLOCK)
								 (LISTP (SETQ NodeID
									    (fetch (GRAPHNODE
										       NODEID)
									       of Node]
					       do (NC.SmashGraphNodeIDProps NodeID)
						    (replace (GRAPHNODE TONODES) of Node
						       with NIL)
						    (replace (GRAPHNODE FROMNODES) of Node
						       with NIL))
					    (NC.MakeLinksLegend Graph Window DropVirtualNodesFlg)
                                                             (* Display the graph.)
					    (NC.ShowBrowserGraph Graph Window)
					    (NC.SetSubstance Card (WINDOWPROP Window
										  (QUOTE GRAPH)))
					    (NC.MarkCardDirty Card)
					    (NC.SetBrowserLinksLegend Card NIL)
					    (NC.ClearMsg Window T])

(NC.ExpandBrowserNode
  [LAMBDA (Window)                                           (* Randy.Gobbel " 4-Mar-87 13:54")

          (* * Ask user to choose a node in the browser and recompute the part of the lattice under that node to the given 
	  depth. And relayout the graph. The code is just a modification of the NC.UpdateBrowserCard code.)



          (* * rht 2/7/86: Now gets and sets browser format, etc. via fetch/set fns.)



          (* * rht 6/10/86: No longer does relayout after expand. Uses NC.LayoutNewBrowserNodes to compute proper locations 
	  of new nodes. Also calls NC.ShowBrowserGraph.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation
	   Card "Expand Node of Browser Card" NIL
	   (PROG (NodeToExpand LinkLabels RootCards RootNodes Lattice LinkIcon OldToNodePairs Graph 
				 GraphNodes NodeLabel OldNode Link BrowserSpecs BrowserFormat 
				 DropVirtualNodesFlg Depth SpecialBrowserSpecs SavedLabelNodes 
				 NewNodes)
	           (SETQ RootCards (NC.FetchBrowserRoots Card))
	           (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
	           (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
                                                             (* If user wants *GRAPH* format, i.e. virtual nodes 
							     eliminated, then set the flag)
	           (if (FMEMB NC.*Graph*BrowserFormat BrowserFormat)
		       then (SETQ DropVirtualNodesFlg T))
	           (SETQ SpecialBrowserSpecs (OR (NC.FetchSpecialBrowserSpecs Card)
						     (create SPECIALBROWSERSPECS)))
	           [SETQ GraphNodes (fetch (GRAPH GRAPHNODES) of (SETQ Graph
									 (WINDOWPROP Window
										       (QUOTE
											 GRAPH]
                                                             (* If there aren't any nodes in graph, then get out 
							     pronto.)
	           (if (NULL GraphNodes)
		       then (NC.PrintMsg Window T "No nodes to expand.")
			      (DISMISS 1000)
			      (NC.ClearMsg Window T)
			      (RETURN NIL))                (* Create hash array if haven't already.)
	           (NC.GetBrowserHashArray Card Graph)
	           (NC.PrintMsg Window T "Pick node to expand." (CHARACTER 13))
                                                             (* Note call to the grapher function READ/NODE to 
							     select a graph node.)
	           (SETQ NodeToExpand (READ/NODE GraphNodes Window))
                                                             (* Can't expand a label node.)
	           (if (NOT (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of 
										     NodeToExpand)))
		       then (NC.PrintMsg NIL T "Sorry, can't expand a label node.")
			      (FLASHW PROMPTWINDOW)
			      (NC.ClearMsg Window T)
			      (RETURN))
	           (SETQ Depth (MKATOM (NC.AskUser "Depth to expand (type integer or INF): " 
							 "--"
							 1 T Window NIL NIL T)))
	           (COND
		     ((EQ Depth (QUOTE INF))
		       (SETQ Depth MAX.FIXP))
		     ((NOT (AND (FIXP Depth)
				    (GREATERP Depth 0)))
		       (NC.PrintMsg Window T "Depth must be an integer greater than 0 or INF.")
		       (RETURN)))
	           (NC.PrintMsg Window T (CHARACTER 13)
				  "Augmenting browser graph. Please wait. ...")
                                                             (* Save the nodes pointed to by the chosen node that 
							     are label nodes. GrowLinkLattice will trash those, so 
							     we restore afterwards.)
	           (SETQ SavedLabelNodes (for ToNode in (fetch (GRAPHNODE TONODES)
								 of NodeToExpand)
					      eachtime (BLOCK)
					      when (AND (NOT (EQ (CAR ToNode)
									 LINKPARAMS))
							    (NOT (NC.LinkIconImageObjP ToNode)))
					      collect ToNode))
                                                             (* Increase link lattice from chosen node to given 
							     depth.)
	           (SETQ Lattice (NC.GrowLinkLattice (LIST (NC.CardFromBrowserNodeID
								   (fetch (GRAPHNODE NODEID)
								      of NodeToExpand)))
							 (APPEND GraphNodes)
							 LinkLabels Card Depth))
	           [AND SavedLabelNodes (replace (GRAPHNODE TONODES) of NodeToExpand
					     with (APPEND SavedLabelNodes (fetch (GRAPHNODE
											 TONODES)
										 of NodeToExpand]
	           (SETQ RootNodes (for RootCard in RootCards collect (NC.GetBrowserNodeID
										Card RootCard)))
	           (NC.SetPropListDirtyFlg Card T)         (* Create Links for all nodes in the new browser graph
							     but not in the old one.)
	           [for Node in Lattice bind NodeID
		      do (COND
			     ((SETQ OldNode (FASSOC (SETQ NodeID (OR (NC.CoerceToGraphNodeID
									       Node)
									     (fetch (GRAPHNODE
											NODEID)
										of Node)))
							GraphNodes))
			       (replace (GRAPHNODE NODELABEL) of Node with (fetch
										   (GRAPHNODE 
											NODELABEL)
										    of OldNode)))
			     (T (replace (GRAPHNODE NODELABEL) of Node
				   with (NC.MakeLinkIcon (NC.MakeLink Window 
								      NC.BrowserContentsLinkLabel
									    (fetch (GRAPHNODE
										       NODELABEL)
									       of Node)
									    Card)))
                                                             (* Make a list of all new nodes.)
				(push NewNodes Node)))     (* Throw away virtual node info.)
			   (AND NodeID (replace (GRAPHNODE NODEID) of Node with NodeID)) 
                                                             (* Untouch each graph node so that next Recompute will
							     put fresh values on proplist.)
			   (NC.GraphNodeIDRemProp NodeID (QUOTE TouchedFlg))
			   (NC.GraphNodeIDRemProp NodeID (QUOTE VisitedFlg)) 
                                                             (* Smash all the unnecessary junk off existing nodes, 
							     letting LAYOUTGRAPH and NC.MakeLinksLegend recompute.)
			   (replace (GRAPHNODE TONODES) of Node
			      with (for ToNode in (fetch (GRAPHNODE TONODES) of Node)
					bind ToNodeID eachtime (BLOCK)
					collect (if (SETQ ToNodeID (NC.CoerceToGraphNodeID
							    ToNode))
						      then 
                                                             (* Throw away link parameterlist info.)
                                                             (* Throw away link dashing info.)
							     (NC.GraphNodeIDPutProp
							       NodeID ToNodeID
							       (for LabelPair
								  in (NC.GraphNodeIDGetProp
									 NodeID ToNodeID)
								  collect (OR (CAR LabelPair)
										  LabelPair)))
							     (NC.GraphNodeIDPutProp
							       ToNodeID NodeID
							       (for LabelPair
								  in (NC.GraphNodeIDGetProp
									 ToNodeID NodeID)
								  collect (OR (CAR LabelPair)
										  LabelPair)))
							     ToNodeID
						    else ToNode]
                                                             (* LAYOUTGRAPH doesn't like duplicate nodes.
							     These get created when virtual nodes are turned into 
							     regular nodes.)
	           (SETQ Lattice (NC.RemoveDuplicateNodesFromGraph Lattice))
	           (NC.RebuildFromNodesInGraph Lattice)
	           (AND NewNodes (NC.LayoutNewBrowserNodes NodeToExpand NewNodes BrowserFormat 
							       SpecialBrowserSpecs))
	           (replace (GRAPH GRAPHNODES) of Graph with Lattice)
                                                             (* Build links legend and fix up TONODES in the 
							     graph.)
	           (NC.SetBrowserLinksLegend Card (NC.MakeLinksLegend Graph Window 
									  DropVirtualNodesFlg))
	           (WINDOWPROP Window (QUOTE GRAPH)
				 Graph)                      (* Display the graph.)
	           (NC.ShowBrowserGraph Graph Window)
	           (NC.SetSubstance Card Graph)
	           (NC.MarkCardDirty Card)
	           (NC.ClearMsg Window T])

(NC.AskBrowserSpecs
  [LAMBDA (MainWindow BrowserCard OldLinkLabels OldDepth OldFormat CreatingBrowserFlg Don'tAskFlg)
                                                             (* pmi: " 2-Apr-87 10:51")

          (* * Puts up the big stylesheet asking user about link types, depth, browser format, etc. The stylesheet returns a 
	  list of 5 things: forward links, backward links, depth, format, and orientation. The last two are smashed together 
	  to form a browserformat and the first two are nconc'ed together. Thus we return a list of 3 things: links, depth, 
	  and browserformat.)



          (* * rht 4/1/85: Now takes Don'tAskFlg arg for when we don't want to ask the user for browser specs.)



          (* * rht 11/17/85: Updated for new card and notefile objects.)



          (* * pmi 4/2/87: Added NC.MenuFont to all menus.)


    (DECLARE (GLOBALVARS NC.MenuFont))
    (PROG ((LinkLabels (NC.RetrieveLinkLabels (fetch (Card NoteFile) of BrowserCard)
						  T))
	     Position Choices ReverseFlg)
	    [if Don'tAskFlg
		then (RETURN (LIST (OR OldLinkLabels LinkLabels)
					 (OR OldDepth 99999)
					 (OR OldFormat (QUOTE (LATTICE]
	    [SETQ Position (AND (WINDOWP MainWindow)
				    (create POSITION
					      XCOORD ← (fetch (REGION LEFT)
							  of (WINDOWPROP MainWindow (QUOTE
									       REGION)))
					      YCOORD ← (fetch (REGION TOP) of (WINDOWREGION
										    MainWindow]
	    (if CreatingBrowserFlg
		then (SETQ OldLinkLabels LinkLabels))
	    (SETQ ReverseFlg (EQ (CADDR OldFormat)
				     (QUOTE REVERSE)))     (* The stylesheet is in a global var.
							     We only need to provide its position, items, and 
							     selections.)
	    (STYLE.PROP NC.BrowserSpecsStylesheet (QUOTE POSITION)
			  Position)
	    (STYLE.PROP NC.BrowserSpecsStylesheet (QUOTE ITEMS)
			  (LIST (create MENU
					    ITEMS ← LinkLabels
					    MENUFONT ← NC.MenuFont)
				  (create MENU
					    ITEMS ← (for Link in LinkLabels
						       collect (PACK* (QUOTE ←)
									  Link))
					    MENUFONT ← NC.MenuFont)
				  (create MENU
					    ITEMS ←
					    (QUOTE (0 1 2 3 4 5 6 7 8 9 INF))
					    MENUFONT ← NC.MenuFont)
				  (create MENU
					    ITEMS ← NC.BrowserFormatOptions
					    MENUFONT ← NC.MenuFont)
				  (create MENU
					    ITEMS ← (QUOTE (Horizontal Vertical Reverse/Horizontal 
									 Reverse/Vertical))
					    MENUFONT ← NC.MenuFont)))
	    [STYLE.PROP NC.BrowserSpecsStylesheet (QUOTE SELECTIONS)
			  (LIST (for Label in OldLinkLabels when (NEQ (NTHCHAR Label 1)
										(QUOTE ←))
				     collect Label)
				  (for Label in OldLinkLabels when (EQ (NTHCHAR Label 1)
									       (QUOTE ←))
				     collect Label)
				  (if (OR (NOT (FIXP OldDepth))
					      (IGREATERP OldDepth 9)
					      (ILESSP OldDepth 0))
				      then (QUOTE INF)
				    else OldDepth)
				  (OR (CAR (FASSOC (CAR OldFormat)
							 NC.BrowserFormatOptions))
					(QUOTE LATTICE))
				  (if (EQ (CADR OldFormat)
					      (QUOTE VERTICAL))
				      then (if ReverseFlg
						 then (QUOTE Reverse/Vertical)
					       else (QUOTE Vertical))
				    else (if ReverseFlg
					       then (QUOTE Reverse/Horizontal)
					     else (QUOTE Horizontal]
	    (SETQ Choices (STYLESHEET NC.BrowserSpecsStylesheet))
	    (RETURN (COND
			[Choices (LIST (APPEND (CAR Choices)
						   (CADR Choices))
					 (OR (FIXP (CADDR Choices))
					       MAX.FIXP)
					 (CONS (CADDDR Choices)
						 (SELECTQ (CADDDR (CDR Choices))
							    (Horizontal (LIST (QUOTE HORIZONTAL)
										(QUOTE 
										REVERSE/DAUGHTERS)))
							    (Vertical (LIST (QUOTE VERTICAL)
									      NIL))
							    (Reverse/Horizontal (LIST (QUOTE
											  HORIZONTAL)
											(QUOTE
											  REVERSE)
											(QUOTE
											  
										REVERSE/DAUGHTERS)))
							    (Reverse/Vertical (LIST (QUOTE 
											 VERTICAL)
										      (QUOTE 
											  REVERSE)))
							    NIL]
			(CreatingBrowserFlg NIL)
			(T (LIST OldLinkLabels OldDepth OldFormat])

(NC.ChangeBrowserSpecs
  [LAMBDA (Window)                                           (* Randy.Gobbel " 4-Mar-87 13:55")

          (* * Change the values of the various browser specs including link types, browser format, search depth, etc.)



          (* * rht 11/17/85: Updated for new card and notefile objects.)



          (* * rht 2/7/86: Now sets and gets browser link labels, etc. via fetch/set fns.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard Window)))
         (NC.ProtectedCardOperation Card "Browser Specs" NIL
				    (PROG (LinkLabels RootNodes BrowserSpecs BrowserFormat Depth)
					    (SETQ LinkLabels (NC.FetchBrowserLinkLabels Card))
					    (SETQ BrowserFormat (NC.FetchBrowserFormat Card))
					    (SETQ Depth (NC.FetchBrowserDepth Card))
					    (SETQ BrowserSpecs (NC.AskBrowserSpecs Window Card 
										       LinkLabels 
										       Depth 
										    BrowserFormat))
					    (SETQ LinkLabels (CAR BrowserSpecs))
					    (SETQ Depth (CADR BrowserSpecs))
					    (SETQ BrowserFormat (CADDR BrowserSpecs))
					    (NC.SetPropListDirtyFlg Card T)
					    (NC.SetBrowserLinkLabels Card LinkLabels)
					    (NC.SetBrowserFormat Card BrowserFormat)
					    (NC.SetBrowserDepth Card Depth)
					    (NC.ClearMsg Window T])

(NC.AskSpecialBrowserSpecs
  (LAMBDA (BrowserWindow)                                    (* rht: "30-May-85 21:44")

          (* * Get the specification for laying out a browser graph from the user and return them in a BrowserSpecs record.)



          (* * rht 3/8/85: Threw out question about browser Format. That is now obtained in NC.AskBrowserSpecs along with 
	  link types, etc.)


    (PROG (BrowserSpecs)
	    (OR (WINDOWP BrowserWindow)
		  (SETQ BrowserWindow))
	    (SETQ BrowserSpecs (create SPECIALBROWSERSPECS
					   Font ← NIL
					   MotherD ←(FIXP (MKATOM (NC.AskUser 
							 "What is the MotherD for this browser? "
										    NIL NIL T 
										    BrowserWindow T)))
					   PersonalD ←(FIXP (MKATOM (OR (NC.AskUser 
							"What is the PersoalD for this browser? "
											    NIL NIL T 
										    BrowserWindow T)
									      10)))
					   FamilyD ←(FIXP (MKATOM (NC.AskUser 
							 "What is the FamilyD for this browser? "
										    NIL NIL T 
										    BrowserWindow T)))
					   ))
	    (RETURN BrowserSpecs))))

(NC.BrowserFlipRoots
  (LAMBDA (Window GraphCard GraphNodes RootCards)            (* rht: "18-Nov-85 21:08")

          (* * Flip to reverse video for each root node in the graph.)



          (* * rht 11/17/85: updated to handle new card and notefile objects.)


    (for RootCard in RootCards bind RootNode
       do (SETQ RootNode (FASSOC (NC.GetBrowserNodeID GraphCard RootCard)
				       GraphNodes))
	    (AND RootNode (FLIPNODE RootNode Window)))))

(NC.SelectGraphNode
  (LAMBDA (Window Graph Mess)                                (* rht: "28-Apr-85 21:05")

          (* * User selects a node from the browser. The node is inverted and returned.)


    (RESETFORM (TTYDISPLAYSTREAM PROMPTWINDOW)
		 (CLRPROMPT)
		 (PROG (NODE)
		         (COND
			   ((NOT (fetch (GRAPH GRAPHNODES) of Graph))
			     (PROMPTPRINT " No nodes in graph.")
			     (RETURN)))
		         (PROMPTPRINT Mess)
		         (SETQ NODE (READ/NODE (fetch (GRAPH GRAPHNODES) of Graph)
						   Window))
		         (TERPRI T)
		         (FLIPNODE NODE Window)
		         (RETURN NODE)))))

(NC.DisplayGraphLinksBetween
  (LAMBDA (FromNode ToNode Window Graph)                     (* rht: "29-Apr-85 00:19")

          (* * Display (or undisplay) the grapher links joining FromNode and ToNode.)


    (PROG (LinkParams ReverseLinkParams)
	    (COND
	      ((SETQ LinkParams (LINKPARAMETERS FromNode ToNode))
		(DISPLAYLINK FromNode ToNode (CONSTANT (create POSITION
								     XCOORD ← 0
								     YCOORD ← 0))
			       Window Graph 1 LinkParams))
	      ((SETQ ReverseLinkParams (LINKPARAMETERS ToNode FromNode))
		(DISPLAYLINK ToNode FromNode (CONSTANT (create POSITION
								     XCOORD ← 0
								     YCOORD ← 0))
			       Window Graph 1 ReverseLinkParams))))))

(NC.RebuildFromNodesInGraph
  (LAMBDA (GraphNodes)                                       (* rht: "31-Aug-85 16:50")

          (* * Remove the FROMNODES from every graph node and rebuild them using the TONODES. Note that there must not be 
	  link param thingies in the TONODES, but virtual nodes are okay.)


    (for Node in GraphNodes bind NodeID NewFromNodes eachtime (BLOCK)
       do (SETQ NodeID (fetch (GRAPHNODE NODEID) of Node))
	    (SETQ NewFromNodes (for OtherNode in GraphNodes when (FMEMB
									   NodeID
									   (fetch (GRAPHNODE 
											  TONODES)
									      of OtherNode))
				    collect (fetch (GRAPHNODE NODEID) of OtherNode)))
	    (replace (GRAPHNODE FROMNODES) of Node with (INTERSECTION NewFromNodes 
									      NewFromNodes)))))

(NC.RemoveDuplicateNodesFromGraph
  (LAMBDA (GraphNodes)                                       (* rht: " 6-Jul-86 17:28")

          (* * There should be no virtual nodes or link param thingies. This removes duplicate nodes coalescing their 
	  TONODES.)


    (LET (DeletedNodeIDs)
         (SETQ GraphNodes (for Node in GraphNodes bind NodeID AlreadyVisitedFlg
			       eachtime (BLOCK)
					  (SETQ NodeID (NC.CoerceToGraphNodeIDOrLabel Node))
					  (if (AND (SETQ AlreadyVisitedFlg (
							   NC.GraphNodeIDGetProp NodeID
										   (QUOTE 
										AlreadyVisitedFlg)))
						       (NOT (FMEMB NodeID DeletedNodeIDs)))
					      then (push DeletedNodeIDs NodeID))
					  (NC.GraphNodeIDPutProp NodeID (QUOTE 
									    CumulativeToNodesList)
								   (UNION (NC.GraphNodeIDGetProp
									      NodeID
									      (QUOTE 
									    CumulativeToNodesList))
									    (fetch (GRAPHNODE
										       TONODES)
									       of Node)))
			       unless AlreadyVisitedFlg collect (NC.GraphNodeIDPutProp
								      NodeID
								      (QUOTE AlreadyVisitedFlg)
								      T)
								    Node))
         (for NodeID in DeletedNodeIDs bind GraphNode
	    do (SETQ GraphNode (FASSOC NodeID GraphNodes))
		 (replace (GRAPHNODE TONODES) of GraphNode with (NC.GraphNodeIDGetProp
									NodeID
									(QUOTE 
									    CumulativeToNodesList))))
         (for Node in GraphNodes bind NodeID
	    do (NC.GraphNodeIDRemProp (SETQ NodeID (NC.CoerceToGraphNodeIDOrLabel Node))
					  (QUOTE CumulativeToNodesList))
		 (NC.GraphNodeIDRemProp NodeID (QUOTE AlreadyVisitedFlg)))
     GraphNodes)))

(NC.ShowBrowserGraph
  [LAMBDA (Graph Window)                                     (* rht: "13-May-87 11:00")

          (* * SHOWGRAPH Graph in Window.)



          (* * rht 5/13/87: Added call to NC.InstallCopyButtonEventFn.)


    (SHOWGRAPH Graph Window (FUNCTION NC.GraphCardLeftButtonFn)
		 (FUNCTION NC.GraphCardMiddleButtonFn)
		 NIL T)

          (* * Have to reset windowprops since SHOWGRAPH messes with them.)

                                                             (* Disable the old-style right button grapher editor 
							     menu.)
    (WINDOWPROP Window (QUOTE RIGHTBUTTONFN)
		  (FUNCTION NC.BrowserRightButtonFn))
    (WINDOWADDPROP Window (QUOTE REPAINTFN)
		     (FUNCTION NC.BrowserRepaintFn)
		     T)
    (WINDOWPROP Window (QUOTE SCROLLFN)
		  (FUNCTION NC.BrowserScrollFn))
    (WINDOWPROP Window (QUOTE RESHAPEFN)
		  (FUNCTION NC.BrowserReshapeFn))
    (NC.InstallTitleBarButtonEventFn Window (FUNCTION NC.TitleBarButtonEventFn))
    (NC.InstallCopyButtonEventFn Window])
)
[DECLARE: EVAL@COMPILE 

(RECORD SPECIALBROWSERSPECS (Font MotherD PersonalD FamilyD)
			      PersonalD ← 10)
]
(* * Graph editor menu functions.)

(DEFINEQ

(NC.GetGraphEditMenu
  [LAMBDA (Window)                                           (* pmi: "25-Mar-87 12:51")

          (* * Create, if necessary, and bring up the graph editor menu.)



          (* * pmi 3/25/87: Added NC.MenuFont to all menus)


    (DECLARE (GLOBALVARS NC.MenuFont NC.GraphEditMenuItems NC.GraphEditUnfixedMenuItems))
    (PROG ((GraphEditUnfixableMenu (WINDOWPROP Window (QUOTE GRAPHEDITUNFIXABLEMENU)))
	     (GraphEditFixableMenu (WINDOWPROP Window (QUOTE GRAPHEDITFIXABLEMENU)))
	     GraphEditMenuWin)                               (* If menu is already up, then put up a menu without 
							     the FIXMENU option, otherwise, allow user to fix 
							     menu.)
	    (if [for Win in (ATTACHEDWINDOWS Window) thereis (AND (OPENWP Win)
									      (WINDOWPROP
										Win
										(QUOTE 
										 GRAPHEDITMENUFLG]
		then [OR GraphEditUnfixableMenu
			     (WINDOWPROP Window (QUOTE GRAPHEDITUNFIXABLEMENU)
					   (SETQ GraphEditUnfixableMenu
					     (create MENU
						       ITEMS ← NC.GraphEditMenuItems
						       TITLE ← " Graph Editor Menu "
						       WHENSELECTEDFN ← (FUNCTION 
							 NC.GraphEditMenuWhenSelectedFn)
						       CHANGEOFFSETFLG ← T
						       CENTERFLG ← T
						       MENUOFFSET ← (CONS -1 0)
						       MENUFONT ← NC.MenuFont
						       ITEMHEIGHT ← (IPLUS (FONTPROP
									       NC.MenuFont
									       (QUOTE HEIGHT))
									     1]
		       (PUTMENUPROP GraphEditUnfixableMenu (QUOTE MAINWINDOW)
				      Window)
		       (MENU GraphEditUnfixableMenu)
	      else [OR GraphEditFixableMenu
			   (WINDOWPROP Window (QUOTE GRAPHEDITFIXABLEMENU)
					 (SETQ GraphEditFixableMenu
					   (create MENU
						     ITEMS ← NC.GraphEditUnfixedMenuItems
						     TITLE ← " Graph Editor Menu "
						     WHENSELECTEDFN ← (FUNCTION 
						       NC.GraphEditMenuWhenSelectedFn)
						     CHANGEOFFSETFLG ← T
						     CENTERFLG ← T
						     MENUOFFSET ← (CONS -1 0)
						     MENUFONT ← NC.MenuFont
						     ITEMHEIGHT ← (IPLUS (FONTPROP NC.MenuFont
										       (QUOTE
											 HEIGHT))
									   1]
		     (PUTMENUPROP GraphEditFixableMenu (QUOTE MAINWINDOW)
				    Window)
		     (MENU GraphEditFixableMenu])

(NC.BrowserRightButtonFn
  (LAMBDA (Window)                                           (* rht: "17-Nov-85 21:18")

          (* * Causes grapher editor menu to come up on right button. If menu is already fixed then brings up menu without 
	  FIXMENU item.)


    (if (INSIDE? (DSPCLIPPINGREGION NIL Window)
		     (LASTMOUSEX Window)
		     (LASTMOUSEY Window))
	then (NC.GetGraphEditMenu Window)
      else (DOWINDOWCOM Window))))

(NC.GraphEditMenuWhenSelectedFn
  (LAMBDA (MenuItem Menu MouseKey)                           (* rht: "10-Apr-85 15:20")

          (* * Called when a selection is made in the graph editor menu. Just call the function, passing it the main window 
	  as arg.)


    (APPLY* (CADR MenuItem)
	      (GETMENUPROP Menu (QUOTE MAINWINDOW)))))

(NC.BrowserCreateCardFn
  (LAMBDA (Window)                                           (* rht: "10-Apr-85 12:34")

          (* * Called from graph edit menu to create card and node. Just sets up the proper ADDNODEFN in graph record and 
	  invokes grapher editor.)


    (replace (GRAPH GRAPH.ADDNODEFN) of (WINDOWPROP Window (QUOTE GRAPH))
       with (FUNCTION NC.BrowserCreateCard))
    (EDITADDNODE Window)))

(NC.BrowserAddLabelFn
  (LAMBDA (Window)                                           (* rht: "25-Apr-85 22:56")

          (* * Called from graph edit menu to add label to graph. Just sets up the proper ADDNODEFN in graph record and 
	  invokes grapher editor.)


    (replace (GRAPH GRAPH.ADDNODEFN) of (WINDOWPROP Window (QUOTE GRAPH))
       with (FUNCTION NC.BrowserAddLabel))
    (EDITADDNODE Window)))

(NC.BrowserAddNodeFn
  (LAMBDA (Window)                                           (* rht: "10-Apr-85 12:34")

          (* * Called from graph edit menu to create browser node for an existing card. Just sets up the proper ADDNODEFN in 
	  graph record and invokes grapher editor.)


    (replace (GRAPH GRAPH.ADDNODEFN) of (WINDOWPROP Window (QUOTE GRAPH))
       with (FUNCTION NC.BrowserAddNode))
    (EDITADDNODE Window)))

(NC.BrowserCreateLinkFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:49")

          (* * Called from graph edit menu to create link and edge.)



          (* * rht 4/20/87: No longer calls EDITAPPLYTOLINK if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITAPPLYTOLINK (FUNCTION NC.BrowserAddLink)
				       (QUOTE added)
				       (WINDOWPROP Window (QUOTE GRAPH))
				       Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't create links: graph has no nodes."])

(NC.BrowserCreateGlobalLinkFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:50")

          (* * Called from graph edit menu to create a global link and edge.)



          (* * rht 4/20/87: No longer calls EDITAPPLYTOLINK if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITAPPLYTOLINK (FUNCTION NC.BrowserAddGlobalLink)
				       (QUOTE added)
				       (WINDOWPROP Window (QUOTE GRAPH))
				       Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't create global links: graph has no nodes."])

(NC.BrowserAddLink
  (LAMBDA (FromNode ToNode Win Graph GlobalLinkFlg)          (* rht: " 6-Jul-86 17:27")

          (* * Like grapher's ADD/AND/DISPLAY/LINK except has different checks and builds a real NC Link.)



          (* * rht 9/20/85: Added GlobalLinkFlg arg to force the link created to be global. Currently, it's global anyway if 
	  from node is a sketch card, for example.)



          (* * rht 11/17/85: updated for new card and notefile object format.)



          (* * rht 2/7/86: Now sets and gets browser link labels, etc. via fetch/set fns.)


    (PROG ((MaxDashingStylesNum (LENGTH NC.DashingStyles))
	     Link Card LabelPairs LabelPair LinkLabel LabelNum ToNodeID FromNodeID OldDestNode 
	     LinkParams ReverseLinkParams SavedDeleteLinkFn NumberOfLinks)
	    (COND
	      ((NOT (AND (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of FromNode))
			     (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of ToNode))))
		(NC.PrintMsg NIL T 
			    "Can't create link from or to a label node.  Try 'Add Edge' instead.")
		(FLASHW PROMPTWINDOW)
		(RETURN NIL))
	      ((SETQ Link (NC.BrowserCreateLink FromNode ToNode Graph Win GlobalLinkFlg))
                                                             (* We successfully created a link.
							     Now undraw existing link and redraw with new one 
							     added.)
                                                             (* First, check whether label for new link is already 
							     in graph.)
		(SETQ Card (NC.CoerceToCard Win))
		(SETQ LabelPairs (NC.FetchBrowserLinksLegend Card))
		(SETQ LinkLabel (fetch (Link Label) of Link))
                                                             (* If link label hasn't appeared in the graph, make a 
							     new dashing number for it and update links legend.)
		(if (NULL (SETQ LabelPair (FASSOC LinkLabel LabelPairs)))
		    then (SETQ LabelPairs (APPEND LabelPairs
							(LIST (SETQ LabelPair
								  (CONS LinkLabel
									  (COND
									    ((ILESSP
										(SETQ LabelNum
										  (LENGTH 
										       LabelPairs))
										MaxDashingStylesNum)
									      (SETQ LabelNum
										(ADD1 LabelNum)))
									    (T LabelNum)))))))
			   (NC.SetBrowserLinksLegend Card LabelPairs)
			   (NC.MakeLinksLegendMenu Win LabelPairs))
		(SETQ FromNodeID (NC.CoerceToGraphNodeID FromNode))
		(SETQ ToNodeID (NC.CoerceToGraphNodeID ToNode))
		(SETQ NumberOfLinks (PLUS (LENGTH (NC.GraphNodeIDGetProp FromNodeID ToNodeID))
					      (LENGTH (NC.GraphNodeIDGetProp ToNodeID FromNodeID))
					      ))
		(SETQ LinkParams (LINKPARAMETERS FromNode ToNode))
		(SETQ ReverseLinkParams (LINKPARAMETERS ToNode FromNode))
		(COND
		  ((OR (ZEROP NumberOfLinks)
			 (AND (NULL LinkParams)
				(NULL ReverseLinkParams)))
		    (if (OR (FMEMB (fetch (GRAPHNODE NODEID) of FromNode)
					 (fetch (GRAPHNODE TONODES) of ToNode))
				(FMEMB (fetch (GRAPHNODE NODEID) of ToNode)
					 (fetch (GRAPHNODE TONODES) of FromNode)))
			then                               (* There are no links, but there is an edge.
							     Delete it and redisplay.)
			       (SETQ SavedDeleteLinkFn (fetch (GRAPH GRAPH.DELETELINKFN)
							    of Graph))
			       (replace (GRAPH GRAPH.DELETELINKFN) of Graph with NIL)
			       (DELETE/AND/DISPLAY/LINK FromNode ToNode Win Graph)
			       (NC.PrintMsg NIL T "Replacing existing edge with new link edge.")
			       (FLASHW PROMPTWINDOW))        (* This is first link between these two nodes so 
							     compute dashing here.)
		    (replace (GRAPHNODE TONODES) of FromNode
		       with (CONS (LIST LINKPARAMS (fetch (GRAPHNODE NODEID) of ToNode)
					      (QUOTE DRAWLINKFN)
					      (FUNCTION NC.BrowserDrawLinkFn)
					      (QUOTE DASHING)
					      (CAR (FNTH NC.DashingStyles (CDR LabelPair))))
				      (fetch (GRAPHNODE TONODES) of FromNode)))
		    (replace (GRAPHNODE FROMNODES) of ToNode with (CONS (fetch
										  (GRAPHNODE NODEID)
										   of FromNode)
										(fetch
										  (GRAPHNODE 
											FROMNODES)
										   of ToNode))))
		  (LinkParams                                (* There are multiple links.
							     And the link params is on the FromNode.)
			      (DISPLAYLINK FromNode ToNode
					     (CONSTANT (create POSITION
								   XCOORD ← 0
								   YCOORD ← 0))
					     Win Graph 1 LinkParams)
                                                             (* If there was only one link, then change so 
							     multi-link indicator.)
			      (if (EQP NumberOfLinks 1)
				  then (RPLACD (CDR LinkParams)
						   (LIST (QUOTE NODEID)
							   FromNodeID
							   (QUOTE DESTNODEID)
							   ToNodeID))))
		  (T                                         (* There are multiple links.
							     The Link params is on the ToNode.)
		     (DISPLAYLINK ToNode FromNode (CONSTANT (create POSITION
									  XCOORD ← 0
									  YCOORD ← 0))
				    Win Graph 1 ReverseLinkParams)
                                                             (* If there was only one link, then change so 
							     multi-link indicator.)
		     (if (EQP NumberOfLinks 1)
			 then (RPLACD (CDR ReverseLinkParams)
					  (LIST (QUOTE NODEID)
						  ToNodeID
						  (QUOTE DESTNODEID)
						  FromNodeID)))))
		(NC.UIDAddProp FromNodeID ToNodeID LabelPair)
		(COND
		  (LinkParams (DISPLAYLINK FromNode ToNode
					     (CONSTANT (create POSITION
								   XCOORD ← 0
								   YCOORD ← 0))
					     Win Graph 1 LinkParams))
		  (ReverseLinkParams (DISPLAYLINK ToNode FromNode
						    (CONSTANT (create POSITION
									  XCOORD ← 0
									  YCOORD ← 0))
						    Win Graph 1 ReverseLinkParams))
		  (T (DISPLAYLINK FromNode ToNode (CONSTANT (create POSITION
									  XCOORD ← 0
									  YCOORD ← 0))
				    Win Graph 1 (LINKPARAMETERS FromNode ToNode))))
		(RETURN NIL))))))

(NC.BrowserAddGlobalLink
  (LAMBDA (FromNode ToNode Win Graph)                        (* rht: "20-Sep-85 14:34")

          (* * This function just allows us to get a GlobalLinkFlg into NC.BrowserAddLink.)


    (NC.BrowserAddLink FromNode ToNode Win Graph T)))

(NC.BrowserAddEdgeFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:51")

          (* * Called from graph edit menu to create edge.)



          (* * rht 4/20/87: No longer calls EDITAPPLYTOLINK if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITAPPLYTOLINK (FUNCTION NC.BrowserAddEdge)
				       (QUOTE added)
				       (WINDOWPROP Window (QUOTE GRAPH))
				       Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't add edges: graph has no nodes."])

(NC.BrowserDeleteCardFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:35")

          (* * Called from graph edit menu to delete card and node.)



          (* * rht 4/20/87: No longer calls NC.BrowserRemoveNode if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (replace (GRAPH GRAPH.DELETENODEFN) of Graph with NIL)
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (NC.BrowserRemoveNode Graph Window T)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't delete card/node: graph has no nodes."])

(NC.BrowserRemoveNodeFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:35")

          (* * Called from graph edit menu to delete a browser node.)



          (* * rht 4/20/87: No longer calls NC.BrowserRemoveNode if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (replace (GRAPH GRAPH.DELETENODEFN) of Graph with NIL)
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (NC.BrowserRemoveNode Graph Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't remove node: graph has no nodes."])

(NC.BrowserDeleteLinkFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:39")

          (* * Called from graph edit menu to delete link and edge.)



          (* * rht 4/20/87: No longer calls EDITMOVENODE if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITAPPLYTOLINK (FUNCTION NC.BrowserDeleteLink)
				       (QUOTE deleted)
				       (WINDOWPROP Window (QUOTE GRAPH))
				       Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't delete link/edge: graph has no nodes."])

(NC.BrowserRemoveEdgeFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:39")

          (* * Called from graph edit menu to remove browser edge.)



          (* * rht 4/20/87: No longer calls EDITAPPLYTOLINK if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITAPPLYTOLINK (FUNCTION NC.BrowserRemoveEdge)
				       (QUOTE removed)
				       (WINDOWPROP Window (QUOTE GRAPH))
				       Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't remove edges: graph has no nodes."])

(NC.BrowserShrinkLabelFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:52")

          (* * Shrink a browser label font.)



          (* * rht 4/20/87: No longer calls EDITCHANGEFONT if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITCHANGEFONT (QUOTE SMALLER)
				      Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't shrink label: graph has no nodes."])

(NC.BrowserGrowLabelFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:52")

          (* * Increase a browser label font.)



          (* * rht 4/20/87: No longer calls EDITCHANGEFONT if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITCHANGEFONT (QUOTE LARGER)
				      Window)
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't expand label: graph has no nodes."])

(NC.BrowserMoveNodeFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:36")

          (* * Move a browser node)



          (* * rht 4/20/87: No longer calls EDITMOVENODE if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITMOVENODE Window)
		    (NC.MarkCardDirty (NC.CoerceToCard Window))
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't move nodes: graph has no nodes."])

(NC.BrowserMoveNodesInRegionFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:45")

          (* * Move all the browser nodes in a region.)



          (* * rht 4/20/87: No longer calls EDITMOVEREGION if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITMOVEREGION Window)
		    (NC.MarkCardDirty (NC.CoerceToCard Window))
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't move nodes: graph has no nodes."])

(NC.BrowserMoveSubtreeFn
  [LAMBDA (Window)                                           (* rht: "20-Apr-87 12:45")

          (* * Move a browser node and all its descendents.)



          (* * rht 4/20/87: No longer calls EDITMOVESUBTREE if graph has no nodes.)


    (LET [(Graph (WINDOWPROP Window (QUOTE GRAPH]
         (if (fetch (GRAPH GRAPHNODES) of Graph)
	     then (EDITMOVESUBTREE Window)
		    (NC.MarkCardDirty (NC.CoerceToCard Window))
	   else (FLASHW PROMPTWINDOW)
		  (NC.PrintMsg NIL T "Can't move nodes: graph has no nodes."])

(NC.BrowserFixGraphEditMenuFn
  [LAMBDA (Window)                                           (* pmi: "25-Mar-87 12:55")

          (* * Attach the Graph edit menu to the side of the browser window. Put it below the links legend.)



          (* * rht 9/20/85: Now uses ADDMENU offscreen so it doesn't flash in lower left corner before coming up.)



          (* * rht 3/3/86: Now does some "random" WINDOWPROPS to make reshaping browser not screw up the attached menu.)



          (* * rht 3/7/86: Uses ATTACHMENU to attach the menu.)



          (* * pmi 3/25/87: Added NC.MenuFont to all menus)


    (DECLARE (GLOBALVARS NC.MenuFont))
    (LET (GraphEditMenu GraphEditMenuWin)
         (SETQ GraphEditMenu (create MENU
					 ITEMS ← NC.GraphEditMenuItems
					 TITLE ← " Editor Menu "
					 WHENSELECTEDFN ← (FUNCTION NC.GraphEditMenuWhenSelectedFn)
					 CHANGEOFFSETFLG ← T
					 CENTERFLG ← T
					 MENUOFFSET ← (CONS -1 0)
					 MENUFONT ← NC.MenuFont
					 ITEMHEIGHT ← (IPLUS (FONTPROP NC.MenuFont (QUOTE
									     HEIGHT))
							       1)))
         (PUTMENUPROP GraphEditMenu (QUOTE MAINWINDOW)
			Window)
         (SETQ GraphEditMenuWin (ATTACHMENU GraphEditMenu Window (QUOTE RIGHT)
						(QUOTE BOTTOM)))
                                                             (* Rig so that close of menu won't close browser.)
         (WINDOWDELPROP GraphEditMenuWin (QUOTE PASSTOMAINCOMS)
			  (QUOTE CLOSEW))
         (WINDOWPROP GraphEditMenuWin (QUOTE GRAPHEDITMENUFLG)
		       T)
         (WINDOWADDPROP GraphEditMenuWin (QUOTE CLOSEFN)
			  (FUNCTION [LAMBDA (W)
			      (DETACHWINDOW W])
			  T])

(NC.BrowserCreateCard
  [LAMBDA (Graph Window)                                     (* rht: "20-Apr-87 15:03")

          (* * Called from grapher ADDNODE fn. Used to create a new card and corresponding browser node.)



          (* * Rht 11/17/85: updated for new card and notefile objects.)



          (* * rht 4/30/86: Now only computes title if got a link.)



          (* * rht 4/20/87: Added ProtectedCardOperation wrapper and call to ALLOW.BUTTON.EVENTS.)


    (LET ((GraphCard (NC.CoerceToCard Window))
	  Link GraphNodeID Card Title)
         (NC.ProtectedCardOperation GraphCard "Create card from browser" Window
				    (SETQ Link (NC.MakeLink Window NC.BrowserContentsLinkLabel
								(QUOTE *New% Card*)
								GraphCard NIL NIL NIL T))
				    (if Link
					then [SETQ Title (NC.RetrieveTitle
						   (SETQ Card (fetch (Link DestinationCard)
								   of Link]
					       (ALLOW.BUTTON.EVENTS)
					       (NC.SetTitle Card
							      (OR (NC.AskUser
								      "Title of new card: " NIL
								      (if (STREQUAL "Untitled" 
											Title)
									  then NIL
									else Title)
								      T Window)
								    "Untitled"))
                                                             (* Create hash array if haven't already.)
					       (NC.GetBrowserHashArray GraphCard Graph)
					       (SETQ GraphNodeID (NC.GetBrowserNodeID GraphCard 
											  Card))
					       (NC.MarkCardDirty GraphCard)
					       (NODECREATE GraphNodeID (NC.MakeLinkIcon Link)
							     (CURSORPOSITION NIL Window))
				      else NIL])

(NC.BrowserCreateLink
  (LAMBDA (FromNode ToNode Graph Window GlobalLinkFlg)       (* rht: "19-Nov-85 12:20")

          (* * Called by grapher when user creates a new link.)



          (* * rht 9/20/85: Added GlobalLinkFlg arg to force the link created to be global. Currently, it's global anyway if 
	  from node is a sketch card, for example.)



          (* * rht 11/17/85: Updated to hancdle new card and notefile formats.)


    (LET ((GraphCard (NC.CoerceToCard Window))
	  SourceCard DestinationCard LinkLabel)
         (if (EQ FromNode ToNode)
	     then (NC.PrintMsg NIL T "Can't create a link from node to itself.")
		    (FLASHW PROMPTWINDOW)
		    NIL
	   else (NC.MarkCardDirty GraphCard)
		  (SETQ SourceCard (NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID FromNode)))
		  (SETQ DestinationCard (NC.CardFromBrowserNodeID (NC.CoerceToGraphNodeID
									ToNode)))
		  (SETQ LinkLabel (COND
		      ((AND (NOT GlobalLinkFlg)
			      (NC.FileBoxP SourceCard T))
			(COND
			  ((NC.FileBoxP DestinationCard T)
			    NC.SubBoxLinkLabel)
			  (T NC.FiledCardLinkLabel)))
		      (T (NC.AskLinkLabel Window NIL NIL T T))))
		  (AND LinkLabel (COND
			   ((AND (NOT GlobalLinkFlg)
				   (NC.TEditBasedP SourceCard))
			     (NCP.LocalGlobalLink LinkLabel SourceCard DestinationCard
						    (QUOTE END)))
			   (T (NCP.GlobalGlobalLink LinkLabel SourceCard DestinationCard))))))))

(NC.BrowserDeleteLink
  [LAMBDA (FromNode ToNode Window Graph)                     (* pmi: "25-Mar-87 14:41")

          (* * Called by grapher when user deletes a link.)



          (* * rht 11/17/85: updated to handle new card and notefile formats.)



          (* * pmi 3/25/87: Added NC.MenuFont to all menus)


    (DECLARE (GLOBALVARS NC.MenuFont))
    (PROG ((GraphCard (NC.CoerceToCard Window))
	     SourceCard SourceType DestinationCard LinkLabel Link Links FromNodeID ToNodeID 
	     LabelPairs MenuItems ExistingLabels LinkAndLabelPair LinkParams ReverseLinkParams)
                                                             (* Be sure this is a link between non-label nodes.)
	    (if [NOT (AND (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of FromNode))
				(NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of ToNode]
		then (NC.PrintMsg Window T 
			 "Can't delete link from or to a label node.  Try 'Remove Edge' instead.")
		       (RETURN NIL))
	    [SETQ SourceCard (NC.CardFromBrowserNodeID (SETQ FromNodeID (
							       NC.CoerceToGraphNodeID FromNode]
	    [SETQ DestinationCard (NC.CardFromBrowserNodeID (SETQ ToNodeID (
								    NC.CoerceToGraphNodeID ToNode]
	    (SETQ Links (NCP.GetLinks SourceCard DestinationCard))
	    (SETQ LabelPairs (NC.GraphNodeIDGetProp FromNodeID ToNodeID))
	    (SETQ ExistingLabels (for Link in Links collect (fetch (Link Label)
								       of Link)))
	    (NC.MarkCardDirty GraphCard)

          (* Let user choose among those edges having links that exist in the real world, and those edges whose corresponding
	  real-life links have been deleted.)


	    [SETQ MenuItems (NCONC [for Link in Links bind LinkLabel LabelPair
					  when (SETQ LabelPair (FASSOC (SETQ LinkLabel
									       (fetch (Link Label)
										  of Link))
									     LabelPairs))
					  collect (LIST LinkLabel
							    (BQUOTE (QUOTE (, Link , LabelPair]
				       (for LabelPair in LabelPairs unless (FMEMB
										   (CAR LabelPair)
										   ExistingLabels)
					  collect (LIST (CAR LabelPair)
							    (BQUOTE (QUOTE (, NIL , LabelPair]
	    [SETQ LinkAndLabelPair
	      (COND
		[(CDR MenuItems)
		  (MENU (create MENU
				    ITEMS ← MenuItems
				    TITLE ← "Which link to delete?"
				    MENUFONT ← NC.MenuFont
				    CENTERFLG ← T
				    ITEMHEIGHT ← (IPLUS (FONTPROP NC.MenuFont (QUOTE HEIGHT))
							  1]
		(T (EVAL (CADAR MenuItems]
	    (COND
	      ((NOT LinkAndLabelPair)
		(FLASHW PROMPTWINDOW)
		(NC.PrintMsg NIL T "No link to delete.")
		(RETURN NIL))
	      ((SETQ Link (CAR LinkAndLabelPair))
		(if (NC.AskYesOrNo (CONCAT "Want to delete the " (fetch (Link Label)
									  of Link)
						 " link between "
						 (NC.RetrieveTitle SourceCard)
						 " and "
						 (NC.RetrieveTitle DestinationCard)
						 "? ")
				       "--"
				       (QUOTE Yes)
				       T Window NIL NIL)
		    then (NCP.DeleteLinks Link)
		  else (RETURN NIL)))
	      ((NOT (NC.YesP (NC.AskUser (CONCAT "Link for that label already deleted."
							 (CHARACTER 13)
							 "Want to delete its edge? ")
					       "- -"
					       (QUOTE Yes)
					       T Window NIL NIL T)))
		(RETURN NIL)))                             (* Undisplay the links between the nodes.)
	    (COND
	      ((SETQ LinkParams (LINKPARAMETERS FromNode ToNode))
		(DISPLAYLINK FromNode ToNode (CONSTANT (create POSITION
								     XCOORD ← 0
								     YCOORD ← 0))
			       Window Graph 1 LinkParams))
	      ((SETQ ReverseLinkParams (LINKPARAMETERS ToNode FromNode))
		(DISPLAYLINK ToNode FromNode (CONSTANT (create POSITION
								     XCOORD ← 0
								     YCOORD ← 0))
			       Window Graph 1 ReverseLinkParams)))
                                                             (* Remove the first occurrence of the label pair from 
							     the proper prop list.)
	    [NC.GraphNodeIDPutProp FromNodeID ToNodeID (for RestOfLabelPairs on LabelPairs
							    bind (LabelPair ← (CADR 
										 LinkAndLabelPair))
							    first (if (EQ LabelPair
										(CAR LabelPairs))
									then (RETURN
										 (CDR LabelPairs)))
							    do (if (EQ LabelPair (CADR 
										 RestOfLabelPairs))
								     then (RPLACD 
										 RestOfLabelPairs
										      (CDDR 
										 RestOfLabelPairs))
									    (RETURN LabelPairs]
                                                             (* If that was the last edge between the two nodes, 
							     then remove the edge from the graph.)
	    (if (AND (NULL (NC.GraphNodeIDGetProp FromNodeID ToNodeID))
			 (NULL (NC.GraphNodeIDGetProp ToNodeID FromNodeID)))
		then (SETQ FromNodeID (fetch (GRAPHNODE NODEID) of FromNode))
		       (SETQ ToNodeID (fetch (GRAPHNODE NODEID) of ToNode))
		       [if LinkParams
			   then (replace (GRAPHNODE TONODES) of FromNode
				     with (for Node in (fetch (GRAPHNODE TONODES)
								of FromNode)
					       unless (EQ (CADR Node)
							      ToNodeID)
					       collect Node))
				  (replace (GRAPHNODE FROMNODES) of ToNode
				     with (DREMOVE FromNodeID (fetch (GRAPHNODE FROMNODES)
								     of ToNode)))
			 else (replace (GRAPHNODE TONODES) of ToNode
				   with (for Node in (fetch (GRAPHNODE TONODES) of ToNode)
					     unless (EQ (CADR Node)
							    FromNodeID)
					     collect Node))
				(replace (GRAPHNODE FROMNODES) of FromNode
				   with (DREMOVE ToNodeID (fetch (GRAPHNODE FROMNODES)
								 of FromNode]
	      else                                         (* Redisplay links between the two nodes.)
		     (if LinkParams
			 then (DISPLAYLINK FromNode ToNode
					       (CONSTANT (create POSITION
								     XCOORD ← 0
								     YCOORD ← 0))
					       Window Graph 1 LinkParams)
		       else (DISPLAYLINK ToNode FromNode
					     (CONSTANT (create POSITION
								   XCOORD ← 0
								   YCOORD ← 0))
					     Window Graph 1 ReverseLinkParams])

(NC.BrowserAddNode
  [LAMBDA (Graph Window)                                     (* Randy.Gobbel " 2-Apr-87 15:38")

          (* * Called by grapher when user creates a new node. Returns new node or nil.)



          (* * rht 11/17/85: updated to handle new card and notefile formats.)



          (* * pmi 12/5/86: Modified message to NC.SelectNoteCards to mention SHIFT-selection. Also added GLOBALVARS 
	  statement.)



          (* * pmi 12/12/86: Removed obsolete ReturnLinksFlg argument in call to NC.SelectNoteCards.)



          (* * rg 3/18/87 added NC.ProtectedCardOperation and NC.CardSelectionOperation wrappers)



          (* * rg 4/2/87 changed NC.CardSelectionOperation to NCP.WithLockedCards)


    (DECLARE (GLOBALVARS NC.BrowserContentsLinkLabel))
    (NC.ProtectedCardOperation (NC.CoerceToCard Window)
			       "Add Node" Window
			       (NCP.WithLockedCards (PROG ((GraphCard (NC.CoerceToCard Window))
							     Link GraphNodeID Card)
                                                             (* Get user to select an existing card.
							     Not allowed to create a new one.)
							    (SETQ Card
							      (NC.SelectNoteCards
								T
								[FUNCTION (LAMBDA (SelectedCard)
								    (COND
								      ((NOT (NC.SameCardP 
										     SelectedCard 
											GraphCard))
									T)
								      (T (NC.PrintMsg Window T 
							      "The browser can't link to itself."
											(CHARACTER
											  13)
											
									     "Selection ignored."
											(CHARACTER
											  13))
									 NIL]
								NC.SelectingCardMenu GraphCard 
					      "Shift-select a card or box to include in browser."))
							    (if (NULL Card)
								then (RETURN NIL))
                                                             (* Make link from browser to new card.)
							    (SETQ Link
							      (NC.MakeLink Window 
								      NC.BrowserContentsLinkLabel 
									     Card GraphCard NIL NIL 
									     NIL T))
                                                             (* Check that it doesn't already exist.
							     If not, create a browser node.)
							    (COND
							      (Link 
                                                             (* Create hash array if haven't already.)
								    (NC.GetBrowserHashArray 
											GraphCard 
											    Graph)
								    [SETQ GraphNodeID
								      (NC.GetBrowserNodeID
									GraphCard
									(SETQ Card
									  (fetch (Link 
										  DestinationCard)
									     of Link]
								    (COND
								      ((for Node
									  in (fetch (GRAPH 
										       GRAPHNODES)
										  of Graph)
									  thereis
									   (EQ GraphNodeID
										 (
									   NC.CoerceToGraphNodeID
										   Node)))
									(NC.PrintMsg Window T 
										"Node for card '"
										       (
										 NC.RetrieveTitle
											 Card)
										       
									    "' already in graph.")
									(NCP.DeleteLinks Link)
									(RETURN NIL)))
								    (NC.MarkCardDirty GraphCard)
								    (RETURN (NODECREATE
										GraphNodeID
										(NC.MakeLinkIcon
										  Link)
										(CURSORPOSITION
										  NIL Window])

(NC.BrowserAddLabel
  (LAMBDA (Graph Window)                                     (* rht: "25-Apr-85 22:55")

          (* * This builds a label node in the default grapher style except that we force non-boxed nodes.)


    (DEFAULT.ADDNODEFN Graph Window NIL)))

(NC.BrowserAddEdge
  (LAMBDA (FromNode ToNode Window Graph)                     (* rht: "17-Nov-85 21:45")

          (* * Called by grapher when user adds a new edge. Will only allow edge addition if there are currently no edges 
	  between the two nodes.)


    (LET ((GraphCard (NC.CoerceToCard Window)))
         (COND
	   ((EQ FromNode ToNode)
	     (NC.PrintMsg NIL T "Can't add edge from a node to itself.")
	     (FLASHW PROMPTWINDOW))
	   ((OR (MEMBTONODES (fetch (GRAPHNODE NODEID) of ToNode)
				 (fetch (GRAPHNODE TONODES) of FromNode))
		  (MEMBTONODES (fetch (GRAPHNODE NODEID) of FromNode)
				 (fetch (GRAPHNODE TONODES) of ToNode)))
	     (NC.PrintMsg NIL T "There is already an edge between those two nodes.")
	     (FLASHW PROMPTWINDOW))
	   (T (NC.MarkCardDirty GraphCard)
	      (ADD/AND/DISPLAY/LINK FromNode ToNode Window Graph)))
     NIL)))

(NC.BrowserRemoveNode
  [LAMBDA (Graph Window DeleteCardFlg NodeToRemove QuietFlg)
                                                             (* Randy.Gobbel "16-Mar-87 18:30")

          (* * Called by grapher when user removes a node.)



          (* * rht 11/17/85: Updated to handle new card and notefile formats.)



          (* * rht 2/7/86: Changed to use NC.SetBrowserRoots instead of NC.PutProp)



          (* * rht 4/30/86: Now takes optional NodeToRemove and QuietFlg argument.)



          (* * rg 3/16/87 NC.DeleteNoteCards -> NC.DeleteNoteCard)


    (PROG ((GraphCard (NC.CoerceToCard Window))
	     Card NodeToRemoveID RootCards NodesToRemove NumVirtuals)
	    [OR NodeToRemove (SETQ NodeToRemove (NC.SelectGraphNode Window Graph
									  (if DeleteCardFlg
									      then 
								 "Choose node of card to delete."
									    else 
									 "Choose node to remove."]
	    (SETQ NodeToRemoveID (NC.CoerceToGraphNodeIDOrLabel NodeToRemove))
	    (SETQ Card (NC.CardFromBrowserNodeID NodeToRemoveID))
                                                             (* If we're supposed to be deleting a card, then check
							     that node represents a card and that user confirms.)
	    (if DeleteCardFlg
		then (if (NC.ValidCardP Card)
			   then (if (NOT (NC.AskYesOrNo (CONCAT "Want to delete the "
									  (NC.RetrieveTitle Card)
									  " card? ")
								"--"
								(QUOTE Yes)
								T Window NIL NIL))
				      then (FLIPNODE NodeToRemove Window)
					     (RETURN (NC.PrintMsg NIL T 
								    "Card & Node delete aborted.")))
			 else (NC.PrintMsg NIL T "No card for that node.")
				(FLASHW PROMPTWINDOW)
				(FLIPNODE NodeToRemove Window)
				(RETURN NIL)))
	    (AND (NC.ValidCardP GraphCard)
		   (NC.MarkCardDirty GraphCard))

          (* We require that all virtual nodes for this node must be removed at once if this one has any link edges to or 
	  from it.)


	    (SETQ NodesToRemove (for Node in (fetch (GRAPH GRAPHNODES) of Graph)
				     when (EQ NodeToRemoveID (NC.CoerceToGraphNodeIDOrLabel
						    Node))
				     collect Node))        (* If there are no edges into or out of this node, 
							     then just delete from graph.)
	    (if (AND (NOT DeleteCardFlg)
			 (NULL (fetch (GRAPHNODE FROMNODES) of NodeToRemove))
			 (NULL (fetch (GRAPHNODE TONODES) of NodeToRemove)))
		then (FLIPNODE NodeToRemove Window)      (* Delete the browsercontents link from the browser.)
		       (if (AND (NC.ValidCardP Card)
				    (NC.ValidCardP GraphCard))
			   then (NC.DelBrowserContentsLink GraphCard Card) 
                                                             (* Remove entry for this node from browser hash 
							     array.)
				  (NC.RemoveBrowserNodeHashArrayEntry GraphCard Card))
		       (RETURN (NC.GraphRemoveNode NodeToRemove Graph Window)))
                                                             (* If there are companion virtual nodes, ask for user 
							     confirmation.)
	    (if [AND (NOT DeleteCardFlg)
			 (GREATERP (SETQ NumVirtuals (LENGTH NodesToRemove))
				     1)
			 (NOT (PROGN (NC.PrintMsg Window T NumVirtuals 
						      " virtual companion nodes will be removed."
							(CHARACTER 13))
					 (NC.YesP (NC.AskUser "Still want to remove? " "--"
								  (QUOTE Yes)
								  NIL Window NIL NIL T]
		then (FLIPNODE NodeToRemove Window)
		       (RETURN NIL))                       (* Delete the browsercontents link from the browser.)
	    (AND (NC.ValidCardP Card)
		   (NC.ValidCardP GraphCard)
		   (NC.DelBrowserContentsLink GraphCard Card))
                                                             (* Delete all record of links to and from this node on
							     prop lists.)
	    (NC.SmashGraphNodeIDProps NodeToRemoveID)
	    (for Node in (fetch (GRAPH GRAPHNODES) of Graph) eachtime (BLOCK)
	       bind UID when (type? UID (SETQ UID (NC.CoerceToGraphNodeID Node)))
	       do (NC.GraphNodeIDRemProp UID NodeToRemoveID))
	    (if (AND (NC.ValidCardP Card)
			 (NC.ValidCardP GraphCard))
		then                                       (* Remove from the root ids list.)
		       (SETQ RootCards (NC.FetchBrowserRoots GraphCard))
		       (if (for RootCard in RootCards eachtime (BLOCK)
				thereis (NC.SameCardP Card RootCard))
			   then (NC.SetBrowserRoots GraphCard (for RootCard in RootCards
								     eachtime (BLOCK)
								     unless (NC.SameCardP Card 
											 RootCard)
								     collect RootCard)))
                                                             (* Remove entry for this node from browser hash 
							     array.)
		       (NC.RemoveBrowserNodeHashArrayEntry GraphCard Card))
                                                             (* Get rid of node and its virtual buddies from 
							     graph.)
	    (AND Window (FLIPNODE NodeToRemove Window))
	    (for Node in NodesToRemove do (NC.GraphRemoveNode Node Graph Window))
                                                             (* Delete card if we're supposed to.)
	    (if DeleteCardFlg
		then (NC.PrintMsg NIL T "Deleting " Card " ... ")
		       (NC.DeleteNoteCard Card)
		       (NC.PrintMsg NIL T "Done." (CHARACTER 13)))
	    (AND Window (REDISPLAYW Window))
	    (OR QuietFlg (NC.PrintMsg NIL T "Nodes: " [CONCATLIST
					    (for Node in NodesToRemove
					       collect (PACK* (fetch (GRAPHNODE NODEID)
								     of Node)
								  (QUOTE % ]
					  "removed."])

(NC.DelBrowserContentsLink
  (LAMBDA (GraphCard DestCard)                               (* kirk: " 5-May-86 14:39")

          (* * Delete the browsercontents link connecting GraphCard and DestID.)



          (* * rht 11/17/85: updated to handle new card and notefile formats.)



          (* * rht 4/30/86: Now checks to make sure there's a link to delete.)


    (LET ((Links (NCP.GetLinks GraphCard DestCard NC.BrowserContentsLinkLabel)))
         (if (CDR Links)
	     then (NC.ReportError "NC.DelBrowserContentsLink" (CONCAT 
						       "Multiple browser contents links between "
									    (NC.FetchTitle 
											GraphCard)
									    " and "
									    (NC.FetchTitle DestCard)
									    ))
		    NIL)
         (AND Links (NC.DeleteLink (CAR Links)
				       NIL T)))))

(NC.BrowserRemoveEdge
  [LAMBDA (FromNode ToNode Window Graph)                     (* pmi: "25-Mar-87 14:41")

          (* * Called by grapher when user deletes an edge. This code is just like NC.BrowserDeleteLink except we don't 
	  affect any notecards links.)



          (* * rht 11/17/85: upadted to handle new card and notefile formats.)



          (* * pmi 3/25/87: Added NC.MenuFont to all menus)


    (DECLARE (GLOBALVARS NC.MenuFont))
    (PROG ((GraphCard (NC.CoerceToCard Window))
	     FromNodeID ToNodeID LabelPairs MenuItems LinkParams ReverseLinkParams LabelPairToRemove)

          (* If this is a link between nodes one of which is non-label, then it must be a non-link edge, so let grapher 
	  handle it.)


	    (if [NOT (AND (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of FromNode))
				(NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of ToNode]
		then (RETURN (DELETE/AND/DISPLAY/LINK FromNode ToNode Window Graph)))
	    (SETQ FromNodeID (NC.CoerceToGraphNodeID FromNode))
	    (SETQ ToNodeID (NC.CoerceToGraphNodeID ToNode))
	    (SETQ LabelPairs (NC.GraphNodeIDGetProp FromNodeID ToNodeID))
	    (if (AND (NULL LabelPairs)
			 (NULL (NC.GraphNodeIDGetProp ToNodeID FromNodeID)))
		then                                       (* No link edges so let grapher try to delete a 
							     non-link edge between these nodes if any.)
		       (RETURN (DELETE/AND/DISPLAY/LINK FromNode ToNode Window Graph)))
	    (NC.MarkCardDirty GraphCard)                   (* Let user choose among all edges from FromNode to 
							     ToNode.)
	    [SETQ MenuItems (for LabelPair in LabelPairs collect (LIST (CAR LabelPair)
										 (BQUOTE
										   (QUOTE , 
											LabelPair]
	    [SETQ LabelPairToRemove
	      (if (CDR MenuItems)
		  then (MENU (create MENU
					   ITEMS ← MenuItems
					   TITLE ← "Which edge to delete?"
					   MENUFONT ← NC.MenuFont
					   CENTERFLG ← T
					   ITEMHEIGHT ← (IPLUS (FONTPROP NC.MenuFont
									     (QUOTE HEIGHT))
								 1)))
		else (EVAL (CADAR MenuItems]
	    (if (NOT LabelPairToRemove)
		then (FLASHW PROMPTWINDOW)
		       (NC.PrintMsg NIL T "No edge to delete.")
		       (RETURN NIL))
	    (SETQ LinkParams (LINKPARAMETERS FromNode ToNode))
	    (SETQ ReverseLinkParams (LINKPARAMETERS ToNode FromNode))
                                                             (* Undisplay the links between the nodes.)
	    (NC.DisplayGraphLinksBetween FromNode ToNode Window Graph)
                                                             (* Remove the first occurrence of the label pair from 
							     the proper prop list.)
	    (NC.GraphNodeIDPutProp FromNodeID ToNodeID (DFIRSTREMOVE LabelPairToRemove LabelPairs)
				     )                       (* If that was the last edge between the two nodes, 
							     then remove the edge from the graph.)
	    (if (AND (NULL (NC.GraphNodeIDGetProp FromNodeID ToNodeID))
			 (NULL (NC.GraphNodeIDGetProp ToNodeID FromNodeID)))
		then (SETQ FromNodeID (fetch (GRAPHNODE NODEID) of FromNode))
		       (SETQ ToNodeID (fetch (GRAPHNODE NODEID) of ToNode))
		       [if LinkParams
			   then (replace (GRAPHNODE TONODES) of FromNode
				     with (for Node in (fetch (GRAPHNODE TONODES)
								of FromNode)
					       unless (EQ (CADR Node)
							      ToNodeID)
					       collect Node))
				  (replace (GRAPHNODE FROMNODES) of ToNode
				     with (DFIRSTREMOVE FromNodeID (fetch (GRAPHNODE FROMNODES)
									  of ToNode)))
			 else (replace (GRAPHNODE TONODES) of ToNode
				   with (for Node in (fetch (GRAPHNODE TONODES) of ToNode)
					     unless (EQ (CADR Node)
							    FromNodeID)
					     collect Node))
				(replace (GRAPHNODE FROMNODES) of FromNode
				   with (DFIRSTREMOVE ToNodeID (fetch (GRAPHNODE FROMNODES)
								      of FromNode]
	      else                                         (* Redisplay links between the two nodes.)
		     (NC.DisplayGraphLinksBetween FromNode ToNode Window Graph])
)
(* * Grapher hacks for browser)

(DEFINEQ

(NC.MakeLinksLegend
  (LAMBDA (Graph Win DropVirtualNodesFlg)                    (* rht: " 6-Jul-86 17:28")

          (* * For every node in the lattice, there should be properties off of its NODEID for each node it's connected to.
	  The values of these props are lists of linklabels. Change these values to also contain the dashing number by 
	  assigning a unique dashing number to each new label we come across. If the global var NC.LinkDashingInBrowser is 
	  non-nil, then put out a menu serving as a legend mapping link label names to dashing styles.
	  If not, then the menu just contains names of link labels.)



          (* * rht 3/9/85: Modified to use Danny's grapher improvements. Now changes destination nodes to be in the new list 
	  format.)



          (* * rht 11/17/85: updated to handle new card and notefile formats.)


    (PROG (LabelPairs (MaxDashingStylesNum (LENGTH NC.DashingStyles))
			ReferencedNodes NumAppearances OldNumAppearances UnderlyingNodeID)
	    (for Node in (fetch (GRAPH GRAPHNODES) of Graph) bind NodeID (LabelNum ← 0)
	       eachtime (BLOCK)
	       do
		(if DropVirtualNodesFlg
		    then                                   (* Throw away the border indicating a virtual node.)
			   (replace (GRAPHNODE NODEBORDER) of Node with NIL))
		(SETQ NodeID (fetch (GRAPHNODE NODEID) of Node))
		(NC.GraphNodeIDPutProp (SETQ UnderlyingNodeID (OR (NC.CoerceToGraphNodeID
									  Node)
									NodeID))
					 (QUOTE NumAppearances)
					 (if (SETQ OldNumAppearances (NC.GraphNodeIDGetProp
						   UnderlyingNodeID
						   (QUOTE NumAppearances)))
					     then (ADD1 OldNumAppearances)
					   else 1))
		(if (NC.LinkIconImageObjP (fetch (GRAPHNODE NODELABEL) of Node))
		    then
		     (replace (GRAPHNODE TONODES) of Node
			with
			 (for DestNode in (fetch (GRAPHNODE TONODES) of Node)
			    eachtime (BLOCK) bind NewLabelPairs Labels DestNodeID NewDestNode 
							NotLabelNodeFlg
			    join                           (* If already computed a LinkParams list, then rip out
							     the ID.)
			     (if (EQ (CAR DestNode)
					 LINKPARAMS)
				 then (SETQ DestNode (CADR DestNode)))
                                                             (* Check for virtual nodes.)
			     (SETQ DestNodeID (if (LISTP DestNode)
						    then (CAR DestNode)
						  else DestNode))
			     (SETQ NewDestNode (if DropVirtualNodesFlg
						     then DestNodeID
						   else DestNode))
			     (SETQ NotLabelNodeFlg (NC.CardFromBrowserNodeID DestNodeID)) 
                                                             (* Turn forward labels into pairs by adding dashing 
							     numbers.)
			     (SETQ NewLabelPairs
			       (if (AND NotLabelNodeFlg
					    (NOT (OR (LISTP (CAR (NC.GraphNodeIDGetProp
									   NodeID DestNodeID)))
							 (LISTP (CAR (NC.GraphNodeIDGetProp
									   DestNodeID NodeID))))))
				   then                    (* Okay to continue since we haven't visited this pair
							     already.)
				    (APPEND (if (SETQ Labels (NC.GraphNodeIDGetProp NodeID 
										       DestNodeID))
						  then
						   (NC.GraphNodeIDPutProp
						     NodeID DestNodeID
						     (for Label in Labels bind Pair
							collect (COND
								    ((NULL (SETQ Pair
									       (FASSOC Label 
										       LabelPairs)))
								      (SETQ Pair
									(CONS Label
										(COND
										  ((ILESSP LabelNum 
									      MaxDashingStylesNum)
										    (SETQ LabelNum
										      (ADD1 
											 LabelNum)))
										  (T LabelNum))))
								      (SETQ LabelPairs
									(CONS Pair LabelPairs))))
								  Pair)))
					      (if (SETQ Labels (NC.GraphNodeIDGetProp 
										       DestNodeID 
											   NodeID))
						  then
						   (NC.GraphNodeIDPutProp
						     DestNodeID NodeID
						     (for Label in Labels bind Pair
							collect (COND
								    ((NULL (SETQ Pair
									       (FASSOC Label 
										       LabelPairs)))
								      (SETQ Pair
									(CONS Label
										(COND
										  ((ILESSP LabelNum 
									      MaxDashingStylesNum)
										    (SETQ LabelNum
										      (ADD1 
											 LabelNum)))
										  (T LabelNum))))
								      (SETQ LabelPairs
									(CONS Pair LabelPairs))))
								  Pair))))))
                                                             (* Likewise for backward labels.)
			     (if NewLabelPairs
				 then                      (* Stick this dest node on the referenced list since 
							     we know a node points to it.)
					(if (NOT (FMEMB NewDestNode ReferencedNodes))
					    then (push ReferencedNodes NewDestNode))
					(LIST (COND
						  ((CDR NewLabelPairs)
                                                             (* There are multiple links joining these two nodes so
							     record nodeids in param list so we can draw flower of 
							     links.)
						    (LIST LINKPARAMS NewDestNode (QUOTE 
										       DRAWLINKFN)
							    (FUNCTION NC.BrowserDrawLinkFn)
							    (QUOTE NODEID)
							    NodeID
							    (QUOTE DESTNODEID)
							    DestNodeID))
						  (T         (* Only one link, so compute dashing style here.)
                                                             (* Check whether link is forward or backward and throw
							     in backward flag if appropriate.)
						     (if (NC.GraphNodeIDGetProp NodeID DestNodeID)
							 then (LIST LINKPARAMS NewDestNode
									(QUOTE DRAWLINKFN)
									(FUNCTION 
									  NC.BrowserDrawLinkFn)
									(QUOTE DASHING)
									(CAR (FNTH 
										 NC.DashingStyles
										       (CDAR 
										    NewLabelPairs))))
						       else (LIST LINKPARAMS NewDestNode
								      (QUOTE DRAWLINKFN)
								      (FUNCTION 
									NC.BrowserDrawLinkFn)
								      (QUOTE DASHING)
								      (CAR (FNTH NC.DashingStyles
										     (CDAR 
										    NewLabelPairs)))
								      (QUOTE BACKWARDFLG)
								      T)))))
			       else                        (* Stick this dest node on the referenced list since 
							     we know a node points to it.)
				      (if (NOT (FMEMB DestNodeID ReferencedNodes))
					  then (push ReferencedNodes DestNodeID))
				      (if (NOT NotLabelNodeFlg)
					  then (LIST DestNodeID)
					else NIL))))))

          (* * Note that the following loop gains time at the expense of space. The space-efficient version would only 
	  generate cons nodes for nodes to be deleted, but would require in general, several walks through the structure.)



          (* Delete all nodes except the ones that either point to something or are pointed to. But keep those unreferenced 
	  nodes that appear exactly once in the graph. They'll wind up being roots.)


	    (replace (GRAPH GRAPHNODES) of Graph
	       with (for Node in (fetch (GRAPH GRAPHNODES) of Graph) eachtime (BLOCK)
			 when (LET* ((UnderlyingNodeID (OR (NC.CoerceToGraphNodeID Node)
							       (fetch (GRAPHNODE NODEID)
								  of Node)))
				       (NumAppearances (NC.GraphNodeIDGetProp UnderlyingNodeID
										(QUOTE 
										   NumAppearances))))
				      (if (OR (fetch (GRAPHNODE TONODES) of Node)
						  (FMEMB (fetch (GRAPHNODE NODEID) of Node)
							   ReferencedNodes)
						  (EQ NumAppearances 1))
					else               (* This node is getting deleted.)
					       (NC.GraphNodeIDPutProp UnderlyingNodeID
									(QUOTE NumAppearances)
									(SUB1 NumAppearances))
					       NIL))
			 collect Node))                    (* Get rid of node borders for virtual nodes that now 
							     only appear once in the graph.
							     Also clean off prop list.)
	    (for Node in (fetch (GRAPH GRAPHNODES) of Graph)
	       do (LET ((UnderlyingNodeID (OR (NC.CoerceToGraphNodeID Node)
						  (fetch (GRAPHNODE NODEID) of Node))))
		         (if (EQ 1 (NC.GraphNodeIDGetProp UnderlyingNodeID (QUOTE 
										   NumAppearances)))
			     then (replace (GRAPHNODE NODEBORDER) of Node with NIL))
		         (NC.GraphNodeIDRemProp UnderlyingNodeID (QUOTE NumAppearances))))
	    (SETQ LabelPairs (DREVERSE LabelPairs))
	    (AND Win (NC.MakeLinksLegendMenu Win LabelPairs))
	    (RETURN LabelPairs))))

(NC.MakeLinksLegendMenu
  [LAMBDA (Win LabelPairs)                                   (* rht: "20-Mar-87 12:37")

          (* * Build a links legend menu and attach to Win)



          (* * rht 1/10/85: Before starting, kill any old links legend menus for Win.)



          (* * rht 1/13/86: Now holds onto value of PASSTOMAINCOMS windowprop of prompt win and restores after reattaching.)



          (* * rht 1/15/86: Added windowprops MINSIZE and MAXSIZE to fix the bug where reshaping browser screws up links 
	  legend menu.)



          (* * rht 3/7/86: Now closes prompt window before attaching menu. Uses ATTACHMENU to attach the menu.)



          (* * rht 4/5/86: Took out call to NC.MoveWindowOntoScreen. For big browsers it causes redraw of window which is too
	  high a price to pay.)



          (* * rht 3/20/87: Changed so that ATTACHMENU call is inside of NC.WithWindowsUnattached macro.
	  Also took out closing of prompt window, as it's no longer necessary.)


    (LET (Menu MenuWin PromptWin MainWinPromptInfo PromptWinPASSTOMAINCOMS)
         (for AttachedWin in (ATTACHEDWINDOWS Win) when (WINDOWPROP AttachedWin
									      (QUOTE 
										  LINKSLEGENDWINP))
	    do (REMOVEWINDOW AttachedWin))
         [SETQ Menu (COND
	     (NC.LinkDashingInBrowser (create MENU
						ITEMS ← [for Pair in LabelPairs
							   join (LIST (CAR Pair)
									  (LIST (QUOTE "  "]
						TITLE ← (QUOTE Links)
						MENUCOLUMNS ← 2))
	     (T (create MENU
			  ITEMS ← (for Pair in LabelPairs collect (CAR Pair))
			  TITLE ← (QUOTE Links)
			  MENUCOLUMNS ← 1]                   (* Stick the links legend window at upper right 
							     corner.)
         [NC.WithTopWindowsUnattached Win (SETQ MenuWin (ATTACHMENU Menu Win (QUOTE RIGHT)
									(QUOTE TOP]
                                                             (* Rig so that close of menu won't close browser.)
         (WINDOWDELPROP MenuWin (QUOTE PASSTOMAINCOMS)
			  (QUOTE CLOSEW))
         (WINDOWADDPROP MenuWin (QUOTE CLOSEFN)
			  (FUNCTION [LAMBDA (W)
			      (DETACHWINDOW W])
			  T)
         (WINDOWADDPROP MenuWin (QUOTE REPAINTFN)
			  (QUOTE NC.LinksLegendRepaintFn))
         (WINDOWADDPROP MenuWin (QUOTE RESHAPEFN)
			  (QUOTE NC.LinksLegendReshapeFn))
         (WINDOWADDPROP MenuWin (QUOTE LINKSLEGENDWINP)
			  T)
         (WINDOWPROP Win (QUOTE NCLABELPAIRS)
		       LabelPairs)
         (if NC.LinkDashingInBrowser
	     then (NC.LinksLegendRepaintFn MenuWin NIL])

(NC.LinksLegendRepaintFn
  (LAMBDA (Win Region)                                       (* rht: "23-Sep-85 15:47")

          (* * Repaint the right-hand column dashing in the browser's links legend menu.)



          (* * rht 7/15/85: Added bail out for case of screwy 1.1 files.)


    (PROG ((Menu (CAR (WINDOWPROP Win (QUOTE MENU))))
	     Items
	     (LabelPairs (WINDOWPROP (MAINWINDOW Win)
				       (QUOTE NCLABELPAIRS))))
	    (SETQ Items (fetch (MENU ITEMS) of Menu))
                                                             (* This little bail out is for case of 1.1 files where
							     label pairs are screwed up and so are menu items.)
	    (if (NULL (CAR Items))
		then (RETURN NIL))
	    (for Item in (CDR Items) by (CDDR Item) as LabelPair in LabelPairs
	       bind ItemRegion
	       do (SETQ ItemRegion (MENUITEMREGION Item Menu))
		    (DRAWLINE (IPLUS 4 (fetch (REGION LEFT) of ItemRegion))
				(IPLUS (QUOTIENT (fetch (REGION HEIGHT) of ItemRegion)
						     2)
					 (fetch (REGION BOTTOM) of ItemRegion))
				(IDIFFERENCE (IPLUS (fetch (REGION WIDTH) of ItemRegion)
							(fetch (REGION LEFT) of ItemRegion))
					       4)
				(IPLUS (QUOTIENT (fetch (REGION HEIGHT) of ItemRegion)
						     2)
					 (fetch (REGION BOTTOM) of ItemRegion))
				1 NIL Win NIL (CAR (FNTH NC.DashingStyles (CDR LabelPair))))))))

(NC.BrowserDrawLinkFn
  (LAMBDA (X1 Y1 X2 Y2 Width Operation Win Color Dashing ParamList)
                                                             (* rht: "27-Aug-85 03:01")

          (* * This is called by grapher to draw a link. If there's no NODEID param then just one link to draw.
	  Check the dashing global var and draw it. Otherwise, there are multiple links so we need to draw a flower 
	  arrangement. Note the ugliness that NC.LinkDashingInBrowser being off means that flowers won't get drawn.
	  If the arrow heads global var is on, then draw arrow head at one end.)


    (BLOCK)
    (PROG (NodeID DestNodeID MidpointFlg ClippingRegion)
	    (COND
	      (NC.LinkDashingInBrowser (COND
					 ((SETQ NodeID (LISTGET ParamList (QUOTE NODEID)))
                                                             (* Multiple links. Have to draw a flower of spline 
							     curves for the links.)
					   (RETURN (NC.DrawFlowerLinks NodeID
									   (SETQ DestNodeID
									     (LISTGET ParamList
											(QUOTE
											  DESTNODEID))
									     )
									   X1 Y1 X2 Y2 Width 
									   Operation Win Color)))))
	      (T (SETQ Dashing NIL)))
	    (COND
	      ((NOT (REGIONSINTERSECTP (CREATEREGION (MIN X1 X2)
							   (MIN Y1 Y2)
							   (ABS (DIFFERENCE X1 X2))
							   (ABS (DIFFERENCE Y1 Y2)))
					   (CREATEREGION (DIFFERENCE (fetch (REGION LEFT)
									    of (SETQ 
										   ClippingRegion
										   (
										DSPCLIPPINGREGION
										     NIL Win)))
									 NC.ArrowHeadLength)
							   (DIFFERENCE (fetch (REGION BOTTOM)
									    of ClippingRegion)
									 NC.ArrowHeadLength)
							   (PLUS (fetch (REGION WIDTH)
								      of ClippingRegion)
								   NC.ArrowHeadLength 
								   NC.ArrowHeadLength)
							   (PLUS (fetch (REGION HEIGHT)
								      of ClippingRegion)
								   NC.ArrowHeadLength 
								   NC.ArrowHeadLength))))
		(RETURN)))
	    (DRAWLINE X1 Y1 X2 Y2 Width Operation Win Color Dashing)
	    (COND
	      ((NEQ NC.ArrowHeadsInBrowser (QUOTE None))
		(SETQ MidpointFlg (EQ NC.ArrowHeadsInBrowser (QUOTE AtMidpoint)))
		(COND
		  ((LISTGET ParamList (QUOTE BACKWARDFLG))
		    (NC.DrawArrowHead X2 Y2 X1 Y1 Width Operation Win Color MidpointFlg))
		  (T (NC.DrawArrowHead X1 Y1 X2 Y2 Width Operation Win Color MidpointFlg))))))))

(NC.DrawFlowerLinks
  (LAMBDA (NodeID1 NodeID2 X1 Y1 X2 Y2 Width Operation Stream Color)
                                                             (* rht: " 6-Jul-86 17:27")

          (* * Expects to find a list of pairs on Node1's ID's proplist under the property with name Node2's ID 
	  (or vice versa) These are pairs of label and dashing number. For each one, draw a spline with one knot using given 
	  dashing number. The more we draw, the farther each gets from the center line. The very first is along the center 
	  line. Subsequent splines alternate on either side of the center line.)



          (* * rht 3/9/85: Now draws first the forward links and then the backward links.)


    (PROG ((Count -1))
	    (for Pair in (NC.GraphNodeIDGetProp NodeID1 NodeID2)
	       do (NC.DrawFlowerLink X1 Y1 X2 Y2 (LIST (QUOTE ROUND)
							     Width Color)
					 (CAR (FNTH NC.DashingStyles (CDR Pair)))
					 (SETQ Count (ADD1 Count))
					 Stream Width Operation Color))
	    (for Pair in (NC.GraphNodeIDGetProp NodeID2 NodeID1)
	       do (NC.DrawFlowerLink X2 Y2 X1 Y1 (LIST (QUOTE ROUND)
							     Width Color)
					 (CAR (FNTH NC.DashingStyles (CDR Pair)))
					 (SETQ Count (ADD1 Count))
					 Stream Width Operation Color)))))

(NC.DrawFlowerLink
  [LAMBDA (X1 Y1 X2 Y2 Brush Dashing Num Win Width Operation Color)
                                                             (* rht: " 1-May-87 14:55")

          (* * Draw one link between given points according to given Dashing. If Num is 0, then draw straight line.
	  Otherwise, draw curves above for odd Num and below for even Num, getting wider for bigger values of Num.)



          (* * rht 3/21/86: Now checks for WINDOWPROP of Scale for when we're in a browser overview window.)



          (* * rht 5/1/87: Changed bogus mention of "Stream" to "Win.")


    (DECLARE (GLOBALVARS NC.ArrowHeadsInBrowser NC.GraphFlowerLinkSeparation))
    (PROG ((MidpointX (QUOTIENT (IPLUS X1 X2)
				    2))
	     (MidpointY (QUOTIENT (IPLUS Y1 Y2)
				    2))
	     XOffset YOffset Scale Window WindowScale)
	    (COND
	      ((ZEROP Num)
		(DRAWLINE X1 Y1 X2 Y2 Width Operation Win Color Dashing)
		(AND (NEQ NC.ArrowHeadsInBrowser (QUOTE None))
		       (NC.DrawArrowHead X1 Y1 X2 Y2 Width Operation Win Color T)))
	      (T                                             (* Check slope of line. If < 45 degrees, then make 
							     spline nodes be vertically removed, otherwise 
							     horizontally removed.)
		 (COND
		   ((GREATERP (ABS (DIFFERENCE X2 X1))
				(ABS (DIFFERENCE Y2 Y1)))
		     [SETQ YOffset (COND
			 ((ODDP Num)
			   (TIMES NC.GraphFlowerLinkSeparation (QUOTIENT (ADD1 Num)
									     2)))
			 (T (MINUS (TIMES NC.GraphFlowerLinkSeparation (QUOTIENT (ADD1 Num)
										       2]
		     (SETQ XOffset 0))
		   (T [SETQ XOffset (COND
			  ((ODDP Num)
			    (TIMES NC.GraphFlowerLinkSeparation (QUOTIENT (ADD1 Num)
									      2)))
			  (T (MINUS (TIMES NC.GraphFlowerLinkSeparation (QUOTIENT (ADD1
											  Num)
											2]
		      (SETQ YOffset 0)))
		 (SETQ Scale (DSPSCALE NIL Win))
		 [SETQ Window (AND (DISPLAYSTREAMP Win)
				       (WINDOWP (WFROMDS Win]
		 (if [AND Window (SETQ WindowScale (WINDOWPROP Window (QUOTE Scale]
		     then (SETQ Scale (FTIMES Scale WindowScale)))
		 (SETQ XOffset (FIXR (TIMES XOffset Scale)))
		 (SETQ YOffset (FIXR (TIMES YOffset Scale)))
		 (DRAWLINE X1 Y1 (PLUS MidpointX XOffset)
			     (PLUS MidpointY YOffset)
			     Width Operation Win NIL Dashing)
		 (DRAWLINE (PLUS MidpointX XOffset)
			     (PLUS MidpointY YOffset)
			     X2 Y2 Width Operation Win NIL Dashing)
		 (AND (NEQ NC.ArrowHeadsInBrowser (QUOTE None))
			(NC.DrawArrowHead X1 Y1 (PLUS MidpointX XOffset)
					    (PLUS MidpointY YOffset)
					    Width Operation Win Color NIL])

(NC.LinksLegendReshapeFn
  (LAMBDA (Window OldImage OldRegion)                        (* rht: " 7-Dec-84 12:15")

          (* * Called when main window is reshaped. Just redisplays the links legend.)


    (REDISPLAYW Window)))

(NC.DrawArrowHead
  (LAMBDA (X1 Y1 X2 Y2 Width Operation Stream Color MidpointFlg XOffset YOffset)
                                                             (* rht: "26-Mar-86 15:45")

          (* * Draw an arrowhead on the end of the line segment from X1,Y1 to X2,Y2.)



          (* * rht 8/12/85: Added check for whether point is inside clipping region before computing arrow head.)



          (* * rht 2/28/86: Now checks for Scale WINDOWPROP on the window. If so, then multiply that in with Scale.
	  We're probably in a shrunken browser in that case.)


    (PROG ((XDiff (FLOAT (IDIFFERENCE X1 X2)))
	     (YDiff (FLOAT (IDIFFERENCE Y1 Y2)))
	     (Window (AND (DISPLAYSTREAMP Stream)
			    (WINDOWP (WFROMDS Stream))))
	     (Scale (DSPSCALE NIL Stream))
	     WindowScale LineLength A11 A12 A21 A22 Tmp1 Tmp2 ClippingRegion ArrowHeadXVal 
	     ArrowHeadYVal ArrowHeadLength)
	    (OR XOffset (SETQ XOffset 0))
	    (OR YOffset (SETQ YOffset 0))
	    (if (AND Window (SETQ WindowScale (WINDOWPROP Window (QUOTE Scale))))
		then (SETQ Scale (FTIMES Scale WindowScale)))
	    (SETQ ArrowHeadXVal (FIXR (TIMES NC.ArrowHeadXVal Scale)))
	    (SETQ ArrowHeadYVal (FIXR (TIMES NC.ArrowHeadYVal Scale)))
	    (SETQ ArrowHeadLength (FIXR (TIMES NC.ArrowHeadLength Scale)))
	    (COND
	      (MidpointFlg (SETQ XOffset (PLUS XOffset (DIFFERENCE (QUOTIENT (IPLUS X1 X2)
										     2)
									 X2)))
			   (SETQ YOffset (PLUS YOffset (DIFFERENCE (QUOTIENT (IPLUS Y1 Y2)
										     2)
									 Y2)))))
                                                             (* If the point at which the arrow head will be drawn 
							     isn't inside the clipping region together with a 
							     border, then bail out.)
	    (SETQ ClippingRegion (DSPCLIPPINGREGION NIL Stream))
	    (COND
	      ((AND ClippingRegion (NOT (INSIDEP (CREATEREGION (DIFFERENCE
									 (fetch (REGION LEFT)
									    of ClippingRegion)
									 ArrowHeadLength)
								       (DIFFERENCE
									 (fetch (REGION BOTTOM)
									    of ClippingRegion)
									 ArrowHeadLength)
								       (PLUS (fetch (REGION
											  WIDTH)
										  of ClippingRegion)
									       ArrowHeadLength 
									       ArrowHeadLength)
								       (PLUS (fetch (REGION
											  HEIGHT)
										  of ClippingRegion)
									       ArrowHeadLength 
									       ArrowHeadLength))
						       (PLUS X2 XOffset)
						       (PLUS Y2 YOffset))))
		(RETURN)))
	    (SETQ LineLength (SQRT (PLUS (TIMES XDiff XDiff)
					       (TIMES YDiff YDiff))))
	    (SETQ A11 (QUOTIENT (FLOAT XDiff)
				    LineLength))
	    (SETQ A21 (QUOTIENT (FLOAT YDiff)
				    LineLength))
	    (SETQ A12 (MINUS A21))
	    (SETQ A22 A11)
	    (SETQ Tmp1 (TIMES A11 ArrowHeadXVal))
	    (SETQ Tmp2 (TIMES A21 ArrowHeadXVal))
	    (SETQ X2 (PLUS X2 XOffset))
	    (SETQ Y2 (PLUS Y2 YOffset))
	    (DRAWLINE X2 Y2 (PLUS X2 Tmp1 (TIMES A12 ArrowHeadYVal))
			(PLUS Y2 Tmp2 (TIMES A22 ArrowHeadYVal))
			Width Operation Stream Color)
	    (DRAWLINE X2 Y2 (PLUS X2 Tmp1 (TIMES A12 (MINUS ArrowHeadYVal)))
			(PLUS Y2 Tmp2 (TIMES A22 (MINUS ArrowHeadYVal)))
			Width Operation Stream Color))))
)
(* * for making and manipulating the tiny attached shrunken browser window.)


(RPAQ? NC.BrowserOverviewDefaultWidth 75)

(RPAQ? NC.BrowserOverviewDefaultHeight 75)

(RPAQ? NC.LeastScaleForGraphNodeShrinking .3)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.BrowserOverviewDefaultWidth NC.BrowserOverviewDefaultHeight 
	    NC.LeastScaleForGraphNodeShrinking NC.BrowserOverviewSpecsStylesheet 
	    NC.DefaultWhereToAttachOverviewWin NC.DefaultBrowserOverviewMode 
	    NC.OverviewWinMode.Compress NC.OverviewWinMode.Expand)
)

(RPAQQ NC.OverviewWinMode.Compress Compress% Overview% Win)

(RPAQQ NC.OverviewWinMode.Expand Expand% Overview)

(RPAQQ NC.DefaultBrowserOverviewMode Neither)

(RPAQ? NC.DefaultWhereToAttachOverviewWin (QUOTE (LEFT . TOP)))

(RPAQ? NC.BrowserOverviewSpecsStylesheet [CREATE.STYLE (QUOTE TITLE)
							 "Choose browser overview specs"
							 (QUOTE ITEM.TITLES)
							 (QUOTE (Edge Position% on% Edge Mode))
							 (QUOTE ITEM.TITLE.FONT)
							 (FONTCOPY MENUFONT (QUOTE WEIGHT)
								   (QUOTE BOLD))
							 (QUOTE ITEMS)
							 (LIST [create MENU ITEMS ←
								       (QUOTE ((LEFT LEFT 
								      "Position along left edge.")
									       (TOP TOP 
								       "Position along top edge.")
									       (RIGHT RIGHT 
								     "Position along right edge.")
									       (BOTTOM BOTTOM 
								    "Position along bottom edge."]
							       [create MENU ITEMS ←
								       (QUOTE ((TOP/RIGHT TOP 
							  "Position at top or right end of edge.")
									       (CENTER CENTER 
								    "Position at center of edge.")
									       (BOTTOM/LEFT BOTTOM 
							    "Position at bottom or left of edge."]
							       (create MENU ITEMS ←
								       (QUOTE ((
Compress% Overview% Win Compress% Overview% Win 
			"Compress the overview window to exactly fit the overview contents.")
									       (Expand% Overview
										 Expand% Overview 
			      "Expand the overview contents to exactly fill the overview window.")
									       (Neither Neither 
			 "Neither expand the overview contents nor compress the overview window."])
(DEFINEQ

(NC.MakeBrowserOverviewWin
  [LAMBDA (BrowserWin Region)                                (* Randy.Gobbel " 4-Mar-87 13:57")

          (* * Make and attach a little window to contain a shrunken bitmap of the entire browser. If Region arg is passed 
	  then use that as size for overview win, else use defaults.)



          (* * rht 3/7/86: Now uses stylesheet to figure out where to attach.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard BrowserWin)))
         (NC.ProtectedCardOperation Card "Build Browser Overview" NIL
				    (LET ((OverviewWinWidth (if Region
								then (fetch (REGION WIDTH)
									  of Region)
							      else (OR (WINDOWPROP
									     BrowserWin
									     (QUOTE 
										 OverviewWinWidth))
									   
								   NC.BrowserOverviewDefaultWidth)))
					  (OverviewWinHeight (if Region
								 then (fetch (REGION HEIGHT)
									   of Region)
							       else (OR (WINDOWPROP
									      BrowserWin
									      (QUOTE 
										OverviewWinHeight))
									    
								  NC.BrowserOverviewDefaultHeight)))
					  [OverviewWin (OPENWP (WINDOWPROP BrowserWin
									       (QUOTE 
									       BrowserOverviewWin]
					  (WhereToAttach (OR (WINDOWPROP BrowserWin (QUOTE
									       
									 WHERETOATTACHOVERVIEWWIN))
							       NC.DefaultWhereToAttachOverviewWin)))
				         (if OverviewWin
					   else            (* Make a new overview window.)
						  (SETQ OverviewWin
						    (CREATEW (CREATEREGION (fetch (POSITION
											  XCOORD)
										  of 
									     NC.OffScreenPosition)
									       (fetch (POSITION
											  YCOORD)
										  of 
									     NC.OffScreenPosition)
									       OverviewWinWidth 
									       OverviewWinHeight)))
						  (WINDOWPROP BrowserWin (QUOTE 
									       BrowserOverviewWin)
								OverviewWin))
				         (NC.ReattachBrowserOverviewWin OverviewWin BrowserWin 
									  WhereToAttach)
				         (NC.RedrawBrowserOverviewWin OverviewWin BrowserWin])

(NC.AskBrowserOverviewSpecs
  [LAMBDA (BrowserWin)                                       (* Randy.Gobbel " 4-Mar-87 14:00")

          (* * Put up stylesheet to get mode and where to attach overview win.)



          (* * rht 11/1/86: Added NC.ProtectedCardOperation wrapper and check for ops in progress.)



          (* * rg 3/4/87 rewritten for new version of NC.ProtectedCardOperation, removed DontCheckOpInProgressFlg)


    (LET ((Card (NC.CoerceToCard BrowserWin)))
         (NC.ProtectedCardOperation Card "Browser Overview Specs" NIL
				    (LET ((WhereLastAttached (OR (WINDOWPROP BrowserWin
										 (QUOTE 
									 WHERETOATTACHOVERVIEWWIN))
								   NC.DefaultWhereToAttachOverviewWin)
							     )
					  (LastMode (OR (WINDOWPROP BrowserWin (QUOTE 
										  OVERVIEWWINMODE))
							  NC.DefaultBrowserOverviewMode))
					  OverviewSpecsResults)
				         (STYLE.PROP NC.BrowserOverviewSpecsStylesheet
						       (QUOTE SELECTIONS)
						       (LIST (CAR WhereLastAttached)
							       (SELECTQ (CDR WhereLastAttached)
									  ((TOP RIGHT)
									    (QUOTE TOP/RIGHT))
									  ((LEFT BOTTOM)
									    (QUOTE BOTTOM/LEFT))
									  (QUOTE CENTER))
							       LastMode))
				         [STYLE.PROP NC.BrowserOverviewSpecsStylesheet
						       (QUOTE POSITION)
						       (create POSITION
								 XCOORD ← (fetch (REGION LEFT)
									     of
									      (WINDOWPROP
										BrowserWin
										(QUOTE REGION)))
								 YCOORD ← (fetch (REGION TOP)
									     of (WINDOWREGION
										    BrowserWin]
				         (if (SETQ OverviewSpecsResults (STYLESHEET 
								NC.BrowserOverviewSpecsStylesheet))
					     then (WINDOWPROP BrowserWin (QUOTE 
									 WHERETOATTACHOVERVIEWWIN)
								  (CONS (CAR OverviewSpecsResults)
									  (CADR 
									     OverviewSpecsResults)))
						    (WINDOWPROP BrowserWin (QUOTE OVERVIEWWINMODE)
								  (CADDR OverviewSpecsResults))
					   else NIL])
)
(DEFINEQ

(NC.DRAWBOX
  (LAMBDA (Left Bottom Width Height LineWidth Operation Stream)
                                                             (* rht: "27-Feb-86 22:34")

          (* * This really SHOULD be in Interlisp. The one in Koto takes no Operation arg.)


    (DRAWLINE Left Bottom (PLUS Left Width)
		Bottom LineWidth Operation Stream)
    (DRAWLINE (PLUS Left Width)
		Bottom
		(PLUS Left Width)
		(PLUS Bottom Height)
		LineWidth Operation Stream)
    (DRAWLINE (PLUS Left Width)
		(PLUS Bottom Height)
		Left
		(PLUS Bottom Height)
		LineWidth Operation Stream)
    (DRAWLINE Left (PLUS Bottom Height)
		Left Bottom LineWidth Operation Stream)))

(NC.ShrinkGraphToWindow
  [LAMBDA (Graph Window)                                     (* Randy.Gobbel "19-Nov-86 15:04")

          (* * Bitblt's into Window a shrunken bitmap of the graph just big enough to fit.)



          (* * rht 3/18/86: Now does more intelligent copy of Graph structure, preserving virtual node eq-ness.)



          (* * rht 3/21/86: Now handles XScale and YScale.)



          (* * rg 11/19/86 Ref. to undef var BrowserWin --> GraphWindow , added GLOBALVARS)


    (DECLARE (GLOBALVARS NC.OverviewWinMode.Expand))
    (LET ((GraphWindow (MAINWINDOW Window))
	  (Scales (NC.ComputeOverviewScale Graph Window))
	  (ShrunkenGraph (create GRAPH using Graph))
	  Scale XScale YScale)
         [if (EQ (WINDOWPROP GraphWindow (QUOTE OVERVIEWWINMODE))
		     NC.OverviewWinMode.Expand)
	     then (SETQ XScale (CAR Scales))
		    (SETQ YScale (CDR Scales))
		    (SETQ Scale (FMIN XScale YScale))
	   else (SETQ Scale (SETQ XScale (SETQ YScale (FMIN (CAR Scales)
								      (CDR Scales]
                                                             (* Shrink the graphnodes.)
         (replace (GRAPH GRAPHNODES) of ShrunkenGraph with (for GraphNode
								    in (fetch (GRAPH GRAPHNODES)
									    of ShrunkenGraph)
								    eachtime (BLOCK)
								    collect (NC.ScaleGraphNode
										(create GRAPHNODE
										   using GraphNode)
										Scale XScale YScale 
										GraphWindow)))
                                                             (* Display the graph, but temporarily scale the 
							     arrowhead global vars. Will this work compiled?)
         (SHOWGRAPH ShrunkenGraph Window)
         (WINDOWPROP Window (QUOTE Scale)
		       Scale)
         (WINDOWPROP Window (QUOTE XScale)
		       XScale)
         (WINDOWPROP Window (QUOTE YScale)
		       YScale)
         (WINDOWPROP Window (QUOTE GRAPH)
		       ShrunkenGraph])

(NC.ScaleGraphNode
  (LAMBDA (GraphNode Scale XScale YScale BrowserWin)         (* rht: "21-Mar-86 00:20")

          (* * Change the position and node label according to Scale.)



          (* * rht 3/14/86: Now smashes NODELABEL field of graph node with bitmap rather than NODELABELBITMAP field.)



          (* * rht 3/18/86: Now returns GraphNode.)



          (* * rht 3/21/86: Now scales position using XScale and YScale. But note that new node size still governed by Scale.
	  This is because SCALEBITMAP only takes single scale.)


    (LET ((OldWidth (fetch (GRAPHNODE NODEWIDTH) of GraphNode))
	  (OldHeight (fetch (GRAPHNODE NODEHEIGHT) of GraphNode))
	  (OldPosition (fetch (GRAPHNODE NODEPOSITION) of GraphNode))
	  NewWidth NewHeight NewBitmap OldBitmap NodeLabel)
         (replace (GRAPHNODE NODEWIDTH) of GraphNode with (SETQ NewWidth
								  (FIX (FTIMES Scale OldWidth))))
         (replace (GRAPHNODE NODEHEIGHT) of GraphNode with (SETQ NewHeight
								   (FIX (FTIMES Scale OldHeight)))
		    )
         (replace (GRAPHNODE NODEPOSITION) of GraphNode
	    with (create POSITION
			     XCOORD ← (FIX (FTIMES XScale (fetch (POSITION XCOORD)
								   of OldPosition)))
			     YCOORD ← (FIX (FTIMES YScale (fetch (POSITION YCOORD)
								   of OldPosition)))))
         (if (LESSP Scale NC.LeastScaleForGraphNodeShrinking)
	     then                                          (* At this scale no need to shrink node label.
							     Just show shaded box.)
		    (SETQ NewBitmap (BITMAPCREATE NewWidth NewHeight))
		    (BLTSHADE GRAYSHADE NewBitmap NIL NIL NewWidth NewHeight)
	   else                                            (* Shrink node label.)
		  (if (SETQ OldBitmap (fetch (GRAPHNODE NODELABELBITMAP) of GraphNode))
		    else (SETQ OldBitmap (BITMAPCREATE OldWidth OldHeight))
			   (SETQ NodeLabel (fetch (GRAPHNODE NODELABEL) of GraphNode))
			   (if (IMAGEOBJP NodeLabel)
			       then (NC.LinkIconDisplayFn NodeLabel (DSPCREATE OldBitmap))
			     else (PRIN1 NodeLabel (DSPCREATE OldBitmap))))
		  (SETQ NewBitmap (SCALEBITMAP OldBitmap Scale)))
         (replace (GRAPHNODE NODELABEL) of GraphNode with NewBitmap)
         (replace (GRAPHNODE NODELABELBITMAP) of GraphNode with NIL)
     GraphNode)))

(NC.ComputeOverviewScale
  (LAMBDA (Graph OverviewWin)                                (* rht: "21-Mar-86 00:13")

          (* * Figure out the scale necessary to shrink Graph into OverviewWin.)



          (* * rht 3/21/86: Now returns both XScale and YScale.)


    (LET ((GraphRegion (GRAPHREGION Graph)))
         (CONS (FMIN (FQUOTIENT (WINDOWPROP OverviewWin (QUOTE WIDTH))
				      (fetch (REGION WIDTH) of GraphRegion))
			 1)
		 (FMIN (FQUOTIENT (WINDOWPROP OverviewWin (QUOTE HEIGHT))
				      (fetch (REGION HEIGHT) of GraphRegion))
			 1)))))

(NC.RedrawBrowserOverviewWin
  [LAMBDA (OverviewWin BrowserWin)                           (* rht: " 8-May-86 11:29")

          (* * The contents of the browser window have changed. Redraw the overview win.)



          (* * rht 3/20/86: Now compresses to fit overview if necessary.)



          (* * rht 5/8/86: Now smashes SCROLLFN)


    (NC.ShrinkGraphToWindow (WINDOWPROP BrowserWin (QUOTE GRAPH))
			      OverviewWin)
    (if (EQ (WINDOWPROP BrowserWin (QUOTE OVERVIEWWINMODE))
		NC.OverviewWinMode.Compress)
	then (WINDOWPROP OverviewWin (QUOTE RESHAPEFN)
			     NIL)
	       (NC.CompressOverviewWin OverviewWin BrowserWin))
    (WINDOWPROP OverviewWin (QUOTE REPAINTFN)
		  (FUNCTION NC.BrowserOverviewWinRepaintFn))
    (WINDOWPROP OverviewWin (QUOTE RESHAPEFN)
		  (FUNCTION NC.BrowserOverviewWinReshapeFn))
    (WINDOWPROP OverviewWin (QUOTE BUTTONEVENTFN)
		  (FUNCTION NC.BrowserOverviewWinButtonEventFn))
    (WINDOWPROP OverviewWin (QUOTE SCROLLFN)
		  NIL)
    (NC.DrawWireFrameInOverviewWin OverviewWin BrowserWin])

(NC.DrawWireFrameInOverviewWin
  (LAMBDA (OverviewWin BrowserWin)                           (* rht: "21-Mar-86 00:35")

          (* * Draw a wire frame in the overview win whose size and position within the overview correspond to the size and 
	  position of BrowserWin relative to entire graph.)



          (* * rht 3/21/86: Now handles XScale and YScale.)


    (LET ((BrowserClippingRegion (DSPCLIPPINGREGION NIL BrowserWin))
	  (XScale (WINDOWPROP OverviewWin (QUOTE XScale)))
	  (YScale (WINDOWPROP OverviewWin (QUOTE YScale)))
	  WireFrame)
         (SETQ WireFrame (CREATEREGION (FIX (FTIMES XScale (fetch (REGION LEFT)
								      of BrowserClippingRegion)))
					   (FIX (FTIMES YScale (fetch (REGION BOTTOM)
								      of BrowserClippingRegion)))
					   (FIX (FTIMES XScale (fetch (REGION WIDTH)
								      of BrowserClippingRegion)))
					   (FIX (FTIMES YScale (fetch (REGION HEIGHT)
								      of BrowserClippingRegion)))))
                                                             (* Draw the wire frame out on the overview window.)
         (NC.DRAWBOX (fetch (REGION LEFT) of WireFrame)
		       (fetch (REGION BOTTOM) of WireFrame)
		       (fetch (REGION WIDTH) of WireFrame)
		       (fetch (REGION HEIGHT) of WireFrame)
		       1
		       (QUOTE INVERT)
		       OverviewWin)                          (* Stash the new wire frame on windowprop.)
         (WINDOWPROP OverviewWin (QUOTE LastWireFrame)
		       WireFrame))))

(NC.CompressOverviewWin
  (LAMBDA (OverviewWin GraphWin)                             (* rht: "21-Mar-86 16:03")

          (* * Reshape OverviewWin so it just holds its contents plus the wire frame.)



          (* * rht 3/21/86: Massive rewrite. Notice ugly use of constant 7 in width of NewRegion. This seems necessary 
	  empirically to keep overview from shrinking with successive redisplays.)


    (LET ((CurCLIPPINGRegion (DSPCLIPPINGREGION NIL OverviewWin))
	  (CurRegion (WINDOWREGION OverviewWin))
	  (WireFrameRegion (WINDOWPROP OverviewWin (QUOTE LastWireFrame)))
	  (GraphRegion (GRAPHREGION (WINDOWPROP OverviewWin (QUOTE GRAPH))))
	  (OverviewWinBorder (WINDOWPROP OverviewWin (QUOTE BORDER)))
	  NewRegion)
         (SETQ NewRegion (create REGION using GraphRegion WIDTH ← (PLUS
						      7
						      (fetch (REGION WIDTH) of GraphRegion))))
         (if (OR (NULL WireFrameRegion)
		     (AND (NOT (EQUAL NewRegion CurCLIPPINGRegion))
			    (REGIONSINTERSECTP WireFrameRegion NewRegion))
		     (PROG1 (SUBREGIONP CurCLIPPINGRegion WireFrameRegion)
			      (SETQ NewRegion (EXTENDREGION NewRegion (INTERSECTREGIONS 
										  WireFrameRegion 
										CurCLIPPINGRegion)))))
	     then (SHAPEW OverviewWin (CREATEREGION (fetch (REGION LEFT) of CurRegion)
							  (fetch (REGION BOTTOM) of CurRegion)
							  (PLUS (TIMES 2 OverviewWinBorder)
								  (fetch (REGION WIDTH)
								     of NewRegion))
							  (PLUS (TIMES 2 OverviewWinBorder)
								  (fetch (REGION HEIGHT)
								     of NewRegion))))
		    (NC.ReattachBrowserOverviewWin OverviewWin GraphWin (WINDOWPROP GraphWin
											(QUOTE
											  
									 WHERETOATTACHOVERVIEWWIN)))))
    ))

(NC.ReattachBrowserOverviewWin
  [LAMBDA (OverviewWin BrowserWin WhereToAttach)             (* rht: " 2-Apr-87 15:12")

          (* * Check to see if OverviewWin is attached at correct place. If not, detach and reattach.)



          (* * rht 3/7/86: No longer checks. Just reattaches.)



          (* * rht 4/2/87: Changed WINDOWDELPROP of PASSTOMAINCOMS to just smash them. Otherwise Shrager's special 
	  SHAPEW.POP, etc. crud hangs around.)


    (LET [(Width (fetch (REGION WIDTH) of (WINDOWREGION OverviewWin)))
	  (Height (fetch (REGION HEIGHT) of (WINDOWREGION OverviewWin]
         (DETACHWINDOW OverviewWin)
         (ATTACHWINDOW OverviewWin BrowserWin (OR (CAR WhereToAttach)
						      (QUOTE LEFT))
			 (OR (CDR WhereToAttach)
			       (QUOTE TOP))
			 (QUOTE LOCALCLOSE))
         (WINDOWPROP OverviewWin (QUOTE PASSTOMAINCOMS)
		       (QUOTE (MOVEW SHAPEW SHRINKW BURYW)))
         (WINDOWPROP BrowserWin (QUOTE OverviewWinWidth)
		       Width)
         (WINDOWPROP BrowserWin (QUOTE OverviewWinHeight)
		       Height)
         (WINDOWPROP OverviewWin (QUOTE MINSIZE)
		       (FUNCTION NC.BrowserOverviewWinMINSIZEFn))
         (WINDOWPROP OverviewWin (QUOTE MAXSIZE)
		       (CONS Width Height])

(NC.BrowserScrollFn
  (LAMBDA (WINDOW XDELTA YDELTA CONTINUOUSFLG)               (* rht: "27-Feb-86 22:49")

          (* * If there's an overview win, then update its wire frame.)


    (LET ((OverviewWin (WINDOWPROP WINDOW (QUOTE BrowserOverviewWin))))
         (if (OPENWP OverviewWin)
	     then (NC.DrawWireFrameInOverviewWin OverviewWin WINDOW)
		    (SCROLLBYREPAINTFN WINDOW XDELTA YDELTA CONTINUOUSFLG)
		    (NC.DrawWireFrameInOverviewWin OverviewWin WINDOW)
	   else (SCROLLBYREPAINTFN WINDOW XDELTA YDELTA CONTINUOUSFLG)))))

(NC.BrowserReshapeFn
  (LAMBDA (Window OldWinBitmap OldWinRegion)                 (* rht: "27-Feb-86 22:48")

          (* * If there's an overview win, then update its wire frame.)


    (LET ((OverviewWin (WINDOWPROP Window (QUOTE BrowserOverviewWin))))
         (if (OPENWP OverviewWin)
	     then (NC.DrawWireFrameInOverviewWin OverviewWin Window)
		    (RESHAPEBYREPAINTFN Window OldWinBitmap OldWinRegion)
		    (NC.DrawWireFrameInOverviewWin OverviewWin Window)
	   else (RESHAPEBYREPAINTFN Window OldWinBitmap OldWinRegion)))))

(NC.BrowserOverviewWinRepaintFn
  (LAMBDA (OverviewWin Region)                               (* rht: " 3-Mar-86 17:57")

          (* * Recomputes overview.)


    (NC.RedrawBrowserOverviewWin OverviewWin (MAINWINDOW OverviewWin))))

(NC.BrowserOverviewWinReshapeFn
  [LAMBDA (OverviewWin OldWinBitmap OldWinRegion)            (* rht: "20-Mar-87 14:33")

          (* * When overview win is reshaped, we need to recompute its contents from scratch. We detach and reattach in case 
	  user pulled it away from browser edge.)



          (* * rht 3/20/87: Now instead of deleting SHAPEW from PASSTOMAINCOMS, it replaces whole list.
	  This is because Shrager's WDWHACKS package adds screwy SHAPEW.mumble things to PASSTOMAINCOMS.)


    (LET [(BrowserWin (MAINWINDOW OverviewWin))
	  (WhereAttached (WINDOWPROP OverviewWin (QUOTE WHEREATTACHED]
         (DETACHWINDOW OverviewWin)
         (ATTACHWINDOW OverviewWin BrowserWin (OR (CAR WhereAttached)
						      (QUOTE LEFT))
			 (OR (CDR WhereAttached)
			       (QUOTE TOP))
			 (QUOTE LOCALCLOSE))
         (WINDOWPROP OverviewWin (QUOTE PASSTOMAINCOMS)
		       (QUOTE (MOVEW SHRINKW BURYW)))
         (WINDOWPROP BrowserWin (QUOTE OverviewWinWidth)
		       (fetch (REGION WIDTH) of (WINDOWREGION OverviewWin)))
         (WINDOWPROP BrowserWin (QUOTE OverviewWinHeight)
		       (fetch (REGION HEIGHT) of (WINDOWREGION OverviewWin)))
         [WINDOWPROP OverviewWin (QUOTE MAXSIZE)
		       (CONS (fetch (REGION WIDTH) of (WINDOWREGION OverviewWin))
			       (fetch (REGION HEIGHT) of (WINDOWREGION OverviewWin]
         (NC.RedrawBrowserOverviewWin OverviewWin BrowserWin])

(NC.BrowserOverviewWinMINSIZEFn
  (LAMBDA (OverviewWin)                                      (* rht: "21-Mar-86 15:17")

          (* * This horrible kludge is so that ATTACHEDWINDOWS sees a different value for MINSIZE depending on whether we're 
	  reshaping the whole browser or just the overview win. In the former case, we want the MINSIZE to be the current 
	  size of the overview win. In the latter, we want it at some small value so user can reduce size of overview win.)


    (LET (Stkpos)
         (PROG1 (if (OR (NULL (SETQ Stkpos (STKPOS (QUOTE SHAPEW))))
			      (NEQ OverviewWin (STKARG (QUOTE WINDOW)
							   (QUOTE SHAPEW)))
			      (SETQ Stkpos (STKPOS (QUOTE RESHAPEALLWINDOWS)
						       NIL NIL Stkpos)))
		      then (LET ((BrowserWin (MAINWINDOW OverviewWin)))
			          (CONS (WINDOWPROP BrowserWin (QUOTE OverviewWinWidth))
					  (WINDOWPROP BrowserWin (QUOTE OverviewWinHeight))))
		    else (QUOTE (5 . 5)))
		  (RELSTK Stkpos)))))

(NC.BrowserOverviewWinButtonEventFn
  (LAMBDA (OverviewWin)                                      (* rht: "21-Mar-86 00:43")

          (* * Called when user buttons in browser overview window. bring cursor to nearest corner of wire frame and let him 
	  reposition wire frame.)



          (* * rht 3/15/86 Now allows moves of wire frame that increase scrolling region.)



          (* * rht 3/21/86: Now handles XScale and YScale.)


    (LET ((LastWireFrame (WINDOWPROP OverviewWin (QUOTE LastWireFrame)))
	  NewRegion XScaleReciprocal YScaleReciprocal BrowserWin OldDisplayRegion NewLeft NewBottom)
         (SETQ NewRegion (GETBOXREGION (fetch (REGION WIDTH) of LastWireFrame)
					   (fetch (REGION HEIGHT) of LastWireFrame)
					   (PLUS (DSPXOFFSET NIL OverviewWin)
						   (fetch (REGION LEFT) of LastWireFrame))
					   (PLUS (DSPYOFFSET NIL OverviewWin)
						   (fetch (REGION BOTTOM) of LastWireFrame))
					   OverviewWin "Please position browser overview wire frame.")
	   )
         (if (REGIONSINTERSECTP NewRegion (DSPCLIPPINGREGION NIL OverviewWin))
	     then (SETQ BrowserWin (MAINWINDOW OverviewWin))
		    (SETQ XScaleReciprocal (FQUOTIENT 1 (WINDOWPROP OverviewWin (QUOTE XScale)
									  )))
		    (SETQ YScaleReciprocal (FQUOTIENT 1 (WINDOWPROP OverviewWin (QUOTE YScale)
									  )))
                                                             (* Where browser used to be.)
		    (SETQ OldDisplayRegion (DSPCLIPPINGREGION NIL BrowserWin)) 
                                                             (* First make sure browser win's EXTENT is big 
							     enough.)
		    (WINDOWPROP BrowserWin (QUOTE EXTENT)
				  (UNIONREGIONS (WINDOWPROP BrowserWin (QUOTE EXTENT))
						  (CREATEREGION
						    (SETQ NewLeft
						      (FIX (FTIMES (fetch (REGION LEFT)
									  of NewRegion)
								       XScaleReciprocal)))
						    (SETQ NewBottom
						      (FIX (FTIMES (fetch (REGION BOTTOM)
									  of NewRegion)
								       YScaleReciprocal)))
						    (fetch (REGION WIDTH) of OldDisplayRegion)
						    (fetch (REGION HEIGHT) of OldDisplayRegion))))
                                                             (* Scroll browser to new region.)
		    (SCROLLW BrowserWin (DIFFERENCE (fetch (REGION LEFT) of OldDisplayRegion)
							NewLeft)
			       (DIFFERENCE (fetch (REGION BOTTOM) of OldDisplayRegion)
					     NewBottom))))))

(NC.BrowserCardQuitFn
  [LAMBDA (Card)                                             (* rht: "25-Apr-87 17:57")

          (* * This clears all UserData fields of Graph node UIDs. I ONLY HAVE TO DO THIS BECAUSE INTERLISP WON'T GC CYCLES!)


    [for GraphNode in (fetch (GRAPH GRAPHNODES) of (NC.FetchSubstance Card))
       do (LET ((GraphNodeID (NC.CoerceToGraphNodeIDOrLabel GraphNode)))
	         (AND (type? UID GraphNodeID)
			(NC.UIDSetPropList GraphNodeID NIL]
    (NCP.ApplySuperTypeFn QuitFn Card])
)
(* * Miscellaneous)

(DEFINEQ

(NC.DelReferencesToCardFromBrowser
  [LAMBDA (SourceCard LinkOrDestinationCard Don'tCreateDeletedImageObjFlg)
                                                             (* rht: "10-Jun-87 15:37")

          (* * Delete from the browser specified by SourceCard all link icon nodes whose DESTINATIONID is eq to 
	  DestinationID. This just checks the case of the SourceCard being a browser root and then passes off to GRAPHCARD's 
	  DelReferencesFn.)



          (* * rht 4/30/86: No longer passes control up to Super's DeleteLinksFn. Work is now done here.)



          (* * rht 9/2/86: Now sets dirtyflg of substance if change was made.)



          (* * rht 11/4/86: Now takes Don'tCreateDeletedImageObjFlg arg.)



          (* * rht 6/10/87: Now cleans up better in case when we're replacing node by deleted link icon.)


    (DECLARE (GLOBALVARS NC.UseDeletedLinkIconIndicatorsFlg NC.DeletedLinkImageObject))
    (LET ((LinkFlg (type? Link LinkOrDestinationCard))
	  (ImageBox (NC.DeletedLinkImageBoxFn NC.DeletedLinkImageObject))
	  LinkIcon Graph DestinationCard BrowserRoots RootCardToDelete UID)
         (if LinkFlg
	     then (OR (NC.CardP SourceCard)
			  (SETQ SourceCard (fetch (Link SourceCard) of LinkOrDestinationCard)))
		    (SETQ DestinationCard (fetch (Link DestinationCard) of 
									    LinkOrDestinationCard))
	   else (SETQ DestinationCard LinkOrDestinationCard))
         (if [SETQ RootCardToDelete (for RootCard in (SETQ BrowserRoots (
								 NC.FetchBrowserRoots SourceCard))
					   eachtime (BLOCK) do (if (NC.SameCardP 
										  DestinationCard 
											 RootCard)
									 then (RETURN RootCard]
	     then (NC.SetBrowserRoots SourceCard (DREMOVE RootCardToDelete BrowserRoots)))
         (SETQ Graph (NC.FetchSubstance SourceCard))
         (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph)
	    when (AND (NC.LinkIconImageObjP (SETQ LinkIcon (fetch (GRAPHNODE NODELABEL)
								      of GraphNode)))
			  (if LinkFlg
			      then (NC.SameLinkP LinkOrDestinationCard (NC.FetchLinkFromLinkIcon
						       LinkIcon))
			    else (NC.SameCardP (fetch (Link DestinationCard)
						      of (NC.FetchLinkFromLinkIcon LinkIcon))
						   DestinationCard)))
	    do (if (AND NC.UseDeletedLinkIconIndicatorsFlg (NOT Don'tCreateDeletedImageObjFlg)
			      )
		     then (replace (GRAPHNODE NODELABEL) of GraphNode with 
									NC.DeletedLinkImageObject)
			    (replace (GRAPHNODE NODEWIDTH) of GraphNode
			       with (fetch (IMAGEBOX XSIZE) of ImageBox))
			    (replace (GRAPHNODE NODEHEIGHT) of GraphNode
			       with (fetch (IMAGEBOX YSIZE) of ImageBox))
			    (NC.RemoveBrowserNodeHashArrayEntry SourceCard DestinationCard)
			    (if (type? UID (SETQ UID (fetch (GRAPHNODE NODEID) of GraphNode)
					     ))
				then (NC.UIDSetPropList UID NIL))
			    (NC.SetSubstanceDirtyFlg SourceCard T)
		   else (NC.BrowserRemoveNode Graph (NC.FetchWindow SourceCard)
						  NIL GraphNode T)))
         (if (AND (NC.ActiveCardP SourceCard)
		      (NC.FetchWindow SourceCard))
	     then (REDISPLAYGRAPH (NC.FetchWindow SourceCard])

(NC.NewBrowserNodeUIDFromOldUID
  (LAMBDA (OldUID GraphNodes HashArray)                      (* rht: " 1-Feb-86 15:59")

          (* * Find and return the NodeID UID in GraphNodes that is SameUIDP to OldUID. Use hash table for caching.)


    (OR (GETHASH OldUID HashArray)
	  (for GraphNode in GraphNodes bind NewUID eachtime (BLOCK)
	     when (NC.SameUIDP OldUID (SETQ NewUID (fetch (GRAPHNODE NODEID) of GraphNode)))
	     do (RETURN (PUTHASH OldUID NewUID HashArray))))))

(NC.GetBrowserSubstance
  [LAMBDA (Card Length Stream VersionNum)                    (* rht: " 4-May-87 20:16")

          (* * Go get all the browser-specific info and then get the graph that is the browser's substance.)



          (* * rht 2/14/86: Added call to NC.ApplySupersFn)



          (* * rht 2/28/86: Added special handling for old version -1 style. I.e. pre 1.3k.)



          (* * fgh 5/1/86 Can't have negative versions, so changed old style to be 255 255.0 Also added defaults for old 
	  style browser specs.)



          (* * fgh 5/25/86 Undid preceeding change w.r.t. the 255 versus -1 Turns out -1 never came from file, only from 
	  converter as an arg.)



          (* * rht 5/4/87: Changed call from NC.ApplySupersFn to APPLY* because otherwise we generate stack overflow for 
	  cards that specialize browser card type.)


    (if (NOT (EQP VersionNum -1))
	then (NC.SetBrowserRootsInfo Card (NC.ReadBrowserRootsInfo Stream))
	       (NC.SetBrowserLinkLabels Card (NC.ReadBrowserLinkLabels Stream))
	       (NC.SetBrowserFormat Card (NC.ReadBrowserFormat Stream))
	       (NC.SetSpecialBrowserSpecs Card (NC.ReadSpecialBrowserSpecs Stream))
	       (NC.SetBrowserDepth Card (NC.ReadBrowserDepth Stream))
	       (NC.SetBrowserLinksLegend Card (NC.ReadBrowserLinksLegend Stream))
	       (NC.SetBrowserSavedLinkingInfo Card (NC.ReadBrowserSavedLinkingInfo Stream))
      else (NC.SetBrowserRootsInfo Card NIL)
	     (NC.SetBrowserLinkLabels Card NIL)
	     (NC.SetBrowserFormat Card NIL)
	     (NC.SetSpecialBrowserSpecs Card NIL)
	     (NC.SetBrowserDepth Card 0)
	     (NC.SetBrowserLinksLegend Card NIL)
	     (NC.SetBrowserSavedLinkingInfo Card NIL))
    (APPLY* (NCP.CardTypeFn (QUOTE Graph)
				(QUOTE GetFn))
	      Card Length Stream VersionNum])

(NC.ComputeBrowserSavedLinkingInfo
  (LAMBDA (Card)                                             (* rht: "30-Apr-86 15:30")

          (* * Search the graph nodeIDs of Card's substance for special linking info for multiple links between same pair of 
	  nodes.)


    (for GraphNode in (fetch (GRAPH GRAPHNODES) of (NC.FetchSubstance Card))
       bind SavedLinkingInfoForNode UID eachtime (BLOCK)
       when (AND (type? UID (SETQ UID (fetch (GRAPHNODE NODEID) of GraphNode)))
		     (SETQ SavedLinkingInfoForNode (NC.ComputeBrowserSavedLinkingInfoForNode
			 UID)))
       collect (CONS UID SavedLinkingInfoForNode))))

(NC.ComputeBrowserSavedLinkingInfoForNode
  (LAMBDA (UID)                                            (* rht: " 7-Feb-86 00:43")

          (* * Return list of DestUIDs and link dashing info.)


    (for UserData on (NC.UIDGetPropList UID) by (CDDR UserData) when (type?
										   UID
										   (CAR UserData))
       join (LIST (CAR UserData)
		      (CADR UserData)))))
)
(DEFINEQ

(NC.FetchBrowserRootsInfo
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:28")

          (* * Return the browser roots UID pairs for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserRootsInfo))))

(NC.FetchBrowserLinkLabels
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:28")

          (* * Return the browser link labels for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserLinkLabels))))

(NC.FetchBrowserFormat
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:28")

          (* * Return the browser format for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserFormat))))

(NC.FetchSpecialBrowserSpecs
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:28")

          (* * Return the special browser specs for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE SpecialBrowserSpecs))))

(NC.FetchBrowserDepth
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:27")

          (* * Return the browser depth for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserDepth))))

(NC.FetchBrowserSavedLinkingInfo
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:27")

          (* * Return the special linking info for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserSavedLinkingInfo))))

(NC.FetchBrowserLinksLegend
  (LAMBDA (Card)                                             (* rht: "11-Feb-86 23:27")

          (* * Return the links legend label pairs for this browser card.)


    (NC.FetchUserDataProp Card (QUOTE BrowserLinksLegend))))
)
(DEFINEQ

(NC.SetBrowserRootsInfo
  (LAMBDA (Card BrowserRootsInfo)                            (* rht: "11-Feb-86 23:30")

          (* * Set the browser card's browser roots pairs.)


    (NC.SetUserDataProp Card (QUOTE BrowserRootsInfo)
			  BrowserRootsInfo)))

(NC.SetBrowserLinkLabels
  (LAMBDA (Card BrowserLinkLabels)                           (* rht: "11-Feb-86 23:30")

          (* * Set the browser card's link labels.)


    (NC.SetUserDataProp Card (QUOTE BrowserLinkLabels)
			  BrowserLinkLabels)))

(NC.SetBrowserFormat
  (LAMBDA (Card BrowserFormat)                               (* rht: "11-Feb-86 23:30")

          (* * Set the browser card's format.)


    (NC.SetUserDataProp Card (QUOTE BrowserFormat)
			  BrowserFormat)))

(NC.SetSpecialBrowserSpecs
  (LAMBDA (Card SpecialBrowserSpecs)                         (* rht: "11-Feb-86 23:30")

          (* * Set the browser card's special browser specs.)


    (NC.SetUserDataProp Card (QUOTE SpecialBrowserSpecs)
			  SpecialBrowserSpecs)))

(NC.SetBrowserDepth
  (LAMBDA (Card BrowserDepth)                                (* rht: "11-Feb-86 23:29")

          (* * Set the browser card's depth.)


    (NC.SetUserDataProp Card (QUOTE BrowserDepth)
			  BrowserDepth)))

(NC.SetBrowserSavedLinkingInfo
  (LAMBDA (Card BrowserSavedLinkingInfo)                     (* rht: "20-Feb-86 11:44")

          (* * Set the browser special linking info.)



          (* * rht 2/20/86: Now returns the value we set to.)


    (NC.SetUserDataProp Card (QUOTE BrowserSavedLinkingInfo)
			  BrowserSavedLinkingInfo)
    BrowserSavedLinkingInfo))

(NC.SetBrowserLinksLegend
  (LAMBDA (Card BrowserLinksLegend)                          (* rht: "11-Feb-86 23:29")

          (* * Set the browser card's links legend label pairs.)


    (NC.SetUserDataProp Card (QUOTE BrowserLinksLegend)
			  BrowserLinksLegend)))
)
(DEFINEQ

(NC.ReadBrowserRootsInfo
  (LAMBDA (Stream)                                           (* rht: "20-Feb-86 14:34")

          (* * Read pairs of UIDs corresponding to card and notefile UIDs for each browser root. These pairs are bounded by 
	  left and right parens.)


    (LET (CharRead)
         (if (NEQ (SETQ CharRead (CHARACTER (BIN Stream)))
		      (QUOTE %())
	     then (NC.ReportError "NC.ReadBrowserRootsInfo" (CONCAT 
						       "Expected to read left paranthesis. Saw: "
									  CharRead)))
         (PROG1 (while (NEQ (CHARACTER (\PEEKBIN Stream))
				  (QUOTE %)))
		     eachtime (BLOCK) collect (CONS (NC.ReadUID Stream)
							    (NC.ReadUID Stream)))
		  (BIN Stream)))))

(NC.ReadBrowserLinkLabels
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:43")

          (* * Read list of link labels from notefile.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PROG1 (READ Stream NC.OrigReadTable)
	     (BIN Stream])

(NC.ReadBrowserFormat
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:43")

          (* * Read browser format from notefile.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PROG1 (READ Stream NC.OrigReadTable)
	     (BIN Stream])

(NC.ReadSpecialBrowserSpecs
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:44")

          (* * Read special browser specs from notefile.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PROG1 (READ Stream NC.OrigReadTable)
	     (BIN Stream])

(NC.ReadBrowserDepth
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:44")

          (* * Read depth from notefile.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (LET ((ThingRead (READ Stream NC.OrigReadTable)))
         (if (NOT (FIXP ThingRead))
	     then (NC.ReportError "NC.ReadBrowserFormat" (CONCAT 
							      "Expected to read a number.  Saw: "
								       ThingRead)))
                                                             (* Skip CR)
         (BIN Stream)
     ThingRead])

(NC.ReadBrowserSavedLinkingInfo
  (LAMBDA (Stream)                                           (* rht: "20-Feb-86 14:36")

          (* * Read lists of info on multiple links between nodes. Each list consists of a UID cons'ed to a prop list of 
	  destination UIDs and link dashing info.)


    (LET (CharRead)
         (if (NEQ (SETQ CharRead (CHARACTER (BIN Stream)))
		      (QUOTE %())
	     then (NC.ReportError "NC.ReadBrowserSavedLinkingInfo" (CONCAT 
						       "Expected to read left paranthesis. Saw: "
										 CharRead)))
         (PROG1 (while (NEQ (CHARACTER (\PEEKBIN Stream))
				  (QUOTE %)))
		     eachtime (BLOCK) collect (NC.ReadBrowserSavedLinkingInfoForNode Stream))
                                                             (* Skip RightParen)
		  (BIN Stream)))))

(NC.ReadBrowserSavedLinkingInfoForNode
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:45")

          (* * Read list of info on multiple links for a particular node. In form of a source UID cons'ed to a prop list of 
	  destination UIDs and link dashing info.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (LET (CharRead SourceUID)
         (if (NEQ (SETQ CharRead (CHARACTER (BIN Stream)))
		      (QUOTE %())
	     then (NC.ReportError "NC.ReadBrowserSavedLinkingInfoForNode" (CONCAT 
						       "Expected to read left paranthesis. Saw: "
											CharRead)))
         (PROG1 [CONS (NC.ReadUID Stream)
			  (while (NEQ (CHARACTER (\PEEKBIN Stream))
					  (QUOTE %)))
			     eachtime (BLOCK) join (PROG1 (LIST (NC.ReadUID Stream)
									  (READ Stream 
										 NC.OrigReadTable))
                                                             (* Skip CR)
								  (BIN Stream]
                                                             (* Skip RightParen)
		  (BIN Stream])

(NC.ReadBrowserLinksLegend
  [LAMBDA (Stream)                                           (* rht: " 1-Nov-86 15:44")

          (* * Read links legend from notefile.)



          (* * rht 11/1/86: Now uses our readtable when reading.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PROG1 (READ Stream NC.OrigReadTable)
	     (BIN Stream])
)
(DEFINEQ

(NC.WriteBrowserRootsInfo
  (LAMBDA (Stream BrowserRootUIDPairs)                       (* rht: " 6-Feb-86 23:30")

          (* * Write pairs of UIDs corresponding to card and notefile UIDs for each browser root. These pairs are bounded by 
	  left and right parens.)


    (PRIN1 (QUOTE %()
	     Stream)
    (for BrowserRootUIDPair in BrowserRootUIDPairs eachtime (BLOCK)
       do (NC.WriteUID Stream (CAR BrowserRootUIDPair))
	    (NC.WriteUID Stream (CDR BrowserRootUIDPair)))
    (PRIN1 (QUOTE %))
	     Stream)))

(NC.WriteBrowserLinkLabels
  [LAMBDA (Stream LinkLabels)                                (* rht: " 1-Nov-86 15:37")

          (* * Write list of link labels from notefile.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRINT LinkLabels Stream NC.OrigReadTable])

(NC.WriteBrowserFormat
  [LAMBDA (Stream Format)                                    (* rht: " 1-Nov-86 15:37")

          (* * Write browser format to notefile.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRINT Format Stream NC.OrigReadTable])

(NC.WriteSpecialBrowserSpecs
  [LAMBDA (Stream LinkLabels)                                (* rht: " 1-Nov-86 15:38")

          (* * Write special browser specs to notefile.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRINT LinkLabels Stream NC.OrigReadTable])

(NC.WriteBrowserDepth
  [LAMBDA (Stream Depth)                                     (* rht: " 1-Nov-86 15:38")

          (* * Write depth to notefile.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRINT Depth Stream NC.OrigReadTable])

(NC.WriteBrowserSavedLinkingInfo
  (LAMBDA (Stream BrowserSavedLinkingInfo)                   (* rht: " 7-Feb-86 00:29")

          (* * Write lists of info on multiple links between nodes. Each list consists of a UID cons'ed to a prop list of 
	  destination UIDs and link dashing info.)


    (PRIN1 (QUOTE %()
	     Stream)
    (for BrowserSavedLinkingInfoForNode in BrowserSavedLinkingInfo eachtime (BLOCK)
       do (NC.WriteBrowserSavedLinkingInfoForNode Stream BrowserSavedLinkingInfoForNode))
    (PRIN1 (QUOTE %))
	     Stream)))

(NC.WriteBrowserSavedLinkingInfoForNode
  [LAMBDA (Stream BrowserSavedLinkingInfoForNode)            (* rht: " 1-Nov-86 15:39")

          (* * Write list of info on multiple links for a particular node. In form of a source UID cons'ed to a prop list of 
	  destination UIDs and link dashing info.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRIN1 (QUOTE %()
	     Stream)
    (NC.WriteUID Stream (CAR BrowserSavedLinkingInfoForNode))
    (for SavedLinkInfo on (CDR BrowserSavedLinkingInfoForNode) by (CDDR SavedLinkInfo)
       eachtime (BLOCK)
       do (NC.WriteUID Stream (CAR SavedLinkInfo))
	    (PRINT (CADR SavedLinkInfo)
		     Stream NC.OrigReadTable))
    (PRIN1 (QUOTE %))
	     Stream])

(NC.WriteBrowserLinksLegend
  [LAMBDA (Stream LinksLegend)                               (* rht: " 1-Nov-86 15:38")

          (* * Write links legend to notefile.)



          (* * rht 11/1/86: Now uses our readtable when printing.)


    (DECLARE (GLOBALVARS NC.OrigReadTable))
    (PRINT LinksLegend Stream NC.OrigReadTable])
)
(DEFINEQ

(NC.GraphLinkIconUpdateCheck
  (LAMBDA (GraphCard Window Graph UpdateIfNullCacheFlg)      (* rht: "20-Feb-86 16:38")

          (* * Check current values of link icon default display global params against values cached on Window.
	  If changed, then fix link icon sizes in graph. Return non-nil if we had to fix graph nodes.)



          (* * rht 2/20/86: Changed to use card's user data area instead of props.)


    (LET ((OldGlobalParams (NC.FetchUserDataProp GraphCard (QUOTE CachedGlobalParams)))
	  (CurGlobalParams (LIST NC.LinkIconShowTitleFlg NC.LinkIconShowLinkTypeFlg 
				   NC.LinkIconAttachBitmapFlg))
	  DidWorkFlg)
         (if (NOT (EQUAL OldGlobalParams CurGlobalParams))
	     then (if (OR OldGlobalParams UpdateIfNullCacheFlg)
			then (for Node in (fetch (GRAPH GRAPHNODES) of Graph)
				  do (NC.GraphNodeLinkIconUpdate Window Node))
			       (SETQ DidWorkFlg T))
		    (NC.SetUserDataProp GraphCard (QUOTE CachedGlobalParams)
					  CurGlobalParams))
     DidWorkFlg)))

(NC.BrowserRepaintFn
  (LAMBDA (Window Region)                                    (* rht: "15-Nov-85 16:05")

          (* * Check if cached global params have changed. If so, fix graph nodes before redisplaying.)


    (NC.GraphLinkIconUpdateCheck (NC.CoerceToCard Window)
				   Window
				   (WINDOWPROP Window (QUOTE GRAPH))
				   NIL)))

(NC.CoerceToGraphNodeID
  (LAMBDA (NodeOrNodeID)                                     (* rht: "26-Nov-85 01:25")

          (* * Extract the graph node ID from a graph node, a virtual node, or a Link params thingie.)


    (if (AND (LISTP NodeOrNodeID)
		 (EQ (CAR NodeOrNodeID)
		       LINKPARAMS))
	then (SETQ NodeOrNodeID (CADR NodeOrNodeID)))
    (if (LISTP NodeOrNodeID)
	then (SETQ NodeOrNodeID (CAR NodeOrNodeID)))
    (if (LISTP NodeOrNodeID)
	then (SETQ NodeOrNodeID (CAR NodeOrNodeID)))
    (AND (type? UID NodeOrNodeID)
	   NodeOrNodeID)))

(NC.CoerceToGraphNodeIDOrLabel
  (LAMBDA (GraphNode)                                        (* rht: "20-Sep-85 12:54")

          (* * This is like NC.CoerceToGraphNodeID except that it returns the label if the node is a label node.
	  Coerces virtual label node ids to labels.)


    (if (NC.CoerceToGraphNodeID GraphNode)
      else (LET ((NodeID (fetch (GRAPHNODE NODEID) of GraphNode)))
	          (if (LISTP NodeID)
		      then (CAR NodeID)
		    else NodeID)))))

(NC.GetBrowserNodeID
  (LAMBDA (BrowserCard NodeCard)                             (* rht: " 6-Jul-86 17:27")

          (* * Create a browser node atom from a new UID. Hang the card object off as a property for those who need it.)



          (* * rht 11/18/85: Now checks to see if NodeCard already appears in graph before creating a new GraphNodeID.
	  Use the browser hash array to do the lookup.)


    (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard))
	  NewUID)
         (if (GETHASH NodeCard HashArray)
	   else (NC.GraphNodeIDPutProp (SETQ NewUID (NC.MakeBrowserNodeUID))
					   (QUOTE CardObject)
					   NodeCard)
		  (PUTHASH NodeCard NewUID HashArray)
		  NewUID))))

(NC.MakeBrowserNodeUID
  (LAMBDA NIL                                                (* rht: "18-Nov-85 21:29")

          (* * Create a standard UID, but make sure it's an atom.)


    (NC.MakeUID)))

(NC.GetBrowserHashArray
  (LAMBDA (BrowserCard Graph)                                (* rht: " 6-Jul-86 17:27")

          (* * Build and install a hash array mapping cards to browsernode UIDs, unless one's already there.
	  If Graph argument is nil, then make a new hash array smashing any existin one.)



          (* * rht 4/30/86: Now makes sure we're not working with a label node instead of a card node.)


    (if (AND Graph (NC.HashArrayFromBrowserCard BrowserCard))
      else (LET ((HashArray (HASHARRAY NC.BrowserHashArraySize)))
	          (NC.SetUserDataProp BrowserCard (QUOTE BrowserHashArray)
					HashArray)
	          (AND Graph (for GraphNode in (fetch (GRAPH GRAPHNODES) of Graph)
				  bind GraphNodeID eachtime (BLOCK) when (SETQ GraphNodeID
										   (
									   NC.CoerceToGraphNodeID
										     GraphNode))
				  do (PUTHASH (NC.GraphNodeIDGetProp GraphNodeID (QUOTE
									     CardObject))
						  GraphNodeID HashArray)))))))

(NC.RemoveBrowserNodeHashArrayEntry
  (LAMBDA (BrowserCard NodeCard)                             (* rht: "18-Nov-85 22:41")

          (* * Remove the entry for given card from given browser's hash array.)


    (LET ((HashArray (NC.HashArrayFromBrowserCard BrowserCard)))
         (if HashArray
	     then (PUTHASH NodeCard NIL HashArray)))))

(NC.HashArrayFromBrowserCard
  (LAMBDA (BrowserCard)                                      (* rht: "18-Nov-85 22:39")

          (* * Return the browser hash array for this browser.)


    (NC.FetchUserDataProp BrowserCard (QUOTE BrowserHashArray))))

(NC.CardFromBrowserNodeID
  (LAMBDA (BrowserNodeID)                                    (* rht: " 6-Jul-86 17:27")

          (* * Extract the card from a browser nodeID.)



          (* * rht 6/10/86: Now checks first for valid UID.)


    (AND (type? UID BrowserNodeID)
	   (NC.GraphNodeIDGetProp BrowserNodeID (QUOTE CardObject)))))

(NC.SmashGraphNodeIDProps
  [LAMBDA (GraphNodeID)                                      (* rht: " 5-Jun-87 15:34")

          (* * Smash the prop list of GraphNodeID except be sure to save the CardObject prop if there is one.)



          (* * rht 6/5/87: Now checks to make sure GraphNodeID is a UID before trying to clear its proplist.)


    (LET ((Card (NC.CardFromBrowserNodeID GraphNodeID)))
         (AND (type? UID GraphNodeID)
		(NC.UIDSetPropList GraphNodeID NIL))
         (AND Card (NC.GraphNodeIDPutProp GraphNodeID (QUOTE CardObject)
					      Card])

(NC.PutBrowserSubstance
  [LAMBDA (Card Stream)                                      (* rht: " 4-May-87 20:14")

          (* * For each BrowserUID, clear its UID prop list. Otherwise HPRINT will die in PutGraphSubstance.)



          (* * rht 1/23/86: Now takes Stream as arg)



          (* * rht 2/1/86: Now saves old UID information on card's proplist for restoring when card is brought up again.
	  Note that this info will only exist for nodes connected to some other node with multiple links.)



          (* * fgh 2/5/86 Added call to NC.ApplySupersFn)



          (* * rht 2/6/86: Now writes down all browser info to substance rather than letting it live on prop list.)



          (* * rht 2/20/86: Now checks to see if saved linking info is cached before recomputing it.)



          (* * fgh 5/25/86 Added default depth paramter.)



          (* * rht 5/4/87: Changed call from NC.ApplySupersFn to APPLY* because otherwise we generate stack overflow for 
	  cards that specialize browser card type.)


    (NC.WriteBrowserRootsInfo Stream (NC.FetchBrowserRootsInfo Card))
    (NC.WriteBrowserLinkLabels Stream (NC.FetchBrowserLinkLabels Card))
    (NC.WriteBrowserFormat Stream (NC.FetchBrowserFormat Card))
    (NC.WriteSpecialBrowserSpecs Stream (NC.FetchSpecialBrowserSpecs Card))
    (NC.WriteBrowserDepth Stream (OR (NC.FetchBrowserDepth Card)
					 0))
    (NC.WriteBrowserLinksLegend Stream (NC.FetchBrowserLinksLegend Card))
    [NC.WriteBrowserSavedLinkingInfo Stream (OR (NC.FetchBrowserSavedLinkingInfo Card)
						    (NC.SetBrowserSavedLinkingInfo Card
										     (
								NC.ComputeBrowserSavedLinkingInfo
										       Card]
    (APPLY* (NCP.CardTypeFn (QUOTE Graph)
				(QUOTE PutFn))
	      Card Stream])

(NC.FetchBrowserRoots
  (LAMBDA (Card)                                             (* rht: " 7-Feb-86 12:29")

          (* * Get roots off Card's UID list and convert them from UID pairs to Card objects.)


    (for BrowserRootUIDPair in (NC.FetchBrowserRootsInfo Card) eachtime (BLOCK)
       collect (NC.CardFromUID (CAR BrowserRootUIDPair)
				   (NC.NoteFileFromNoteFileUID (CDR BrowserRootUIDPair))))))

(NC.SetBrowserRoots
  [LAMBDA (Card BrowserRoots)                                (* rht: " 6-Feb-87 18:38")

          (* * Put the roots on the Card's UID property list in the CardUID/NoteFileUID pair format.)



          (* * rht 2/6/87: Now checks that BrowserRoots are valid cards.)


    (NC.SetBrowserRootsInfo Card (for BrowserRoot in BrowserRoots eachtime (BLOCK)
				      when (NC.ValidCardP BrowserRoot)
				      collect (CONS (fetch (Card UID) of BrowserRoot)
							(fetch (NoteFile UID)
							   of (fetch (Card NoteFile)
								   of BrowserRoot])
)
(DEFINEQ

(NC.GraphNodeIDGetProp
  (LAMBDA (GraphNodeID PropName)                             (* rht: " 6-Jul-86 17:22")

          (* * Do a GETPROP either to the UID or to the atom if it's a label.)


    (if (type? UID GraphNodeID)
	then (NC.UIDGetProp GraphNodeID PropName)
      else (GETPROP GraphNodeID PropName))))

(NC.GraphNodeIDPutProp
  (LAMBDA (GraphNodeID PropName Value)                       (* rht: " 6-Jul-86 17:23")

          (* * Do a PUTPROP either to the UID or to the atom if it's a label.)


    (if (type? UID GraphNodeID)
	then (NC.UIDPutProp GraphNodeID PropName Value)
      else (PUTPROP GraphNodeID PropName Value))))

(NC.GraphNodeIDRemProp
  (LAMBDA (GraphNodeID PropName)                             (* rht: " 6-Jul-86 17:23")

          (* * Do a REMPROP either to the UID or to the atom if it's a label.)


    (if (type? UID GraphNodeID)
	then (NC.UIDRemProp GraphNodeID PropName)
      else (REMPROP GraphNodeID PropName))))
)
(DECLARE: DOEVAL@COMPILE DONTCOPY

(GLOBALVARS NC.ArrowHeadLength NC.ArrowHeadAngle NC.ArrowHeadXVal NC.ArrowHeadYVal)
)

(RPAQQ NC.ArrowHeadLength 7)

(RPAQQ NC.ArrowHeadAngle 20)

(RPAQ NC.ArrowHeadXVal (TIMES NC.ArrowHeadLength (COS NC.ArrowHeadAngle)))

(RPAQ NC.ArrowHeadYVal (TIMES NC.ArrowHeadLength (SIN NC.ArrowHeadAngle)))
(* * init)

(DEFINEQ

(NC.AddBrowserCard
  [LAMBDA NIL                                                (* rht: "25-Apr-87 17:58")

          (* * fgh 11/14/85 Updated to handle merge of card and substance types.)



          (* * rht 4/7/86: Added middle button menu items.)



          (* * rht 4/25/87: Added QuitFn)


    (NC.AddCardType (QUOTE Browser)
		      (QUOTE Graph)
		      [BQUOTE ((MakeFn , (FUNCTION NC.MakeBrowserCard))
				 (EditFn , (FUNCTION NC.BringUpBrowserCard))
				 (PutFn , (FUNCTION NC.PutBrowserSubstance))
				 (GetFn , (FUNCTION NC.GetBrowserSubstance))
				 (DeleteLinksFn , (FUNCTION NC.DelReferencesToCardFromBrowser))
				 (QuitFn , (FUNCTION NC.BrowserCardQuitFn]
		      (BQUOTE ((LinkDisplayMode Title)
				 (DefaultHeight 350)
				 (DefaultWidth 500)
				 (DisplayedInMenuFlg , T)
				 (LeftButtonMenuItems , (for Item in (NC.GetCardTypeField
									   LeftButtonMenuItems
									   (QUOTE Graph))
							   collect (if (EQ (CAR Item)
										 (QUOTE 
										     Insert% Link))
									 then 
								      NC.GlobalInsertLinkMenuItem
								       else Item)))
				 (MiddleButtonMenuItems , (QUOTE ((Recompute% Browser
								       (FUNCTION 
									 NC.UpdateBrowserCard)
								       
			     "Recomputes this browser to show the current state of the NoteFile.")
								     (Relayout% Graph
								       (FUNCTION 
									 NC.RelayoutBrowserCard)
								       
						    "Re-layout the browser, but keep same nodes.")
								     (Reconnect% Nodes
								       (FUNCTION 
									 NC.ConnectNodesInBrowser)
								       
	   "Draw all possible links, from currently selected link types, between pairs of nodes.")
								     (Unconnect% Nodes
								       (FUNCTION 
								       NC.UnconnectNodesInBrowser)
								       
							       "Undraw all links in the browser.")
								     (Expand% Browser% Node
								       (FUNCTION 
									 NC.ExpandBrowserNode)
								       
					      "Expand the graph under one node to a given depth.")
								     (Graph% Edit% Menu
								       (FUNCTION 
									 NC.GetGraphEditMenu)
								       
								"Bring up the graph editor menu.")
								     (Change% Browser% Specs
								       (FUNCTION 
									 NC.ChangeBrowserSpecs)
								       
		 "Make changes to some or all of the browser specs, e.g. link types, depth, etc.")
								     (Browser% Overview% Win
								       (FUNCTION 
									NC.MakeBrowserOverviewWin)
								       
							    "Attach the browser overview window.")
								     (Change% Overview% Specs
								       (FUNCTION 
								       NC.AskBrowserOverviewSpecs)
								       
			      "Change the browser overview specs: where to attach and what mode."])
)
(NC.AddBrowserCard)
(DEFINEQ

(NCAddStub.BrowserCard
  (LAMBDA NIL                                                (* rht: " 8-Nov-86 19:21")

          (* * kirk 18Jun86 Add the Browser card stub)



          (* * rht 11/7/86: Now passes down a \\FILLME// field.)


    (NC.AddCardTypeStub (QUOTE Browser)
			  (QUOTE Graph)
			  (QUOTE NCBROWSERCARD)
			  NIL
			  (QUOTE ((DisplayedInMenuFlg T)))
			  (QUOTE (LinkIconAttachedBitMap)))))
)
(PUTPROPS NCBROWSERCARD COPYRIGHT ("Xerox Corporation" 1985 1986 1987))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (14793 28960 (NC.MakeBrowserCard 14803 . 23449) (NC.BringUpBrowserCard 23451 . 28958)) (
28961 90271 (NC.GrowLinkLattice 28971 . 37494) (NC.UpdateBrowserCard 37496 . 49404) (
NC.RelayoutBrowserCard 49406 . 56342) (NC.LayoutNewBrowserNodes 56344 . 59492) (
NC.ConnectNodesInBrowser 59494 . 65890) (NC.UnconnectNodesInBrowser 65892 . 68399) (
NC.ExpandBrowserNode 68401 . 77181) (NC.AskBrowserSpecs 77183 . 81741) (NC.ChangeBrowserSpecs 81743 . 
83329) (NC.AskSpecialBrowserSpecs 83331 . 84483) (NC.BrowserFlipRoots 84485 . 84994) (
NC.SelectGraphNode 84996 . 85688) (NC.DisplayGraphLinksBetween 85690 . 86435) (
NC.RebuildFromNodesInGraph 86437 . 87318) (NC.RemoveDuplicateNodesFromGraph 87320 . 89159) (
NC.ShowBrowserGraph 89161 . 90269)) (90430 137394 (NC.GetGraphEditMenu 90440 . 92859) (
NC.BrowserRightButtonFn 92861 . 93343) (NC.GraphEditMenuWhenSelectedFn 93345 . 93712) (
NC.BrowserCreateCardFn 93714 . 94169) (NC.BrowserAddLabelFn 94171 . 94620) (NC.BrowserAddNodeFn 94622
 . 95091) (NC.BrowserCreateLinkFn 95093 . 95778) (NC.BrowserCreateGlobalLinkFn 95780 . 96493) (
NC.BrowserAddLink 96495 . 103018) (NC.BrowserAddGlobalLink 103020 . 103297) (NC.BrowserAddEdgeFn 
103299 . 103969) (NC.BrowserDeleteCardFn 103971 . 104628) (NC.BrowserRemoveNodeFn 104630 . 105281) (
NC.BrowserDeleteLinkFn 105283 . 105974) (NC.BrowserRemoveEdgeFn 105976 . 106665) (
NC.BrowserShrinkLabelFn 106667 . 107231) (NC.BrowserGrowLabelFn 107233 . 107796) (NC.BrowserMoveNodeFn
 107798 . 108372) (NC.BrowserMoveNodesInRegionFn 108374 . 108981) (NC.BrowserMoveSubtreeFn 108983 . 
109591) (NC.BrowserFixGraphEditMenuFn 109593 . 111339) (NC.BrowserCreateCard 111341 . 113040) (
NC.BrowserCreateLink 113042 . 114583) (NC.BrowserDeleteLink 114585 . 121256) (NC.BrowserAddNode 121258
 . 124698) (NC.BrowserAddLabel 124700 . 124977) (NC.BrowserAddEdge 124979 . 125940) (
NC.BrowserRemoveNode 125942 . 132039) (NC.DelBrowserContentsLink 132041 . 132900) (
NC.BrowserRemoveEdge 132902 . 137392)) (137433 161592 (NC.MakeLinksLegend 137443 . 146601) (
NC.MakeLinksLegendMenu 146603 . 149330) (NC.LinksLegendRepaintFn 149332 . 150908) (
NC.BrowserDrawLinkFn 150910 . 153481) (NC.DrawFlowerLinks 153483 . 154855) (NC.DrawFlowerLink 154857
 . 157746) (NC.LinksLegendReshapeFn 157748 . 157992) (NC.DrawArrowHead 157994 . 161590)) (163744 
168296 (NC.MakeBrowserOverviewWin 163754 . 166151) (NC.AskBrowserOverviewSpecs 166153 . 168294)) (
168297 187670 (NC.DRAWBOX 168307 . 169019) (NC.ShrinkGraphToWindow 169021 . 171125) (NC.ScaleGraphNode
 171127 . 173683) (NC.ComputeOverviewScale 173685 . 174314) (NC.RedrawBrowserOverviewWin 174316 . 
175464) (NC.DrawWireFrameInOverviewWin 175466 . 177095) (NC.CompressOverviewWin 177097 . 178995) (
NC.ReattachBrowserOverviewWin 178997 . 180359) (NC.BrowserScrollFn 180361 . 180949) (
NC.BrowserReshapeFn 180951 . 181538) (NC.BrowserOverviewWinRepaintFn 181540 . 181792) (
NC.BrowserOverviewWinReshapeFn 181794 . 183359) (NC.BrowserOverviewWinMINSIZEFn 183361 . 184445) (
NC.BrowserOverviewWinButtonEventFn 184447 . 187108) (NC.BrowserCardQuitFn 187110 . 187668)) (187697 
194854 (NC.DelReferencesToCardFromBrowser 187707 . 191201) (NC.NewBrowserNodeUIDFromOldUID 191203 . 
191752) (NC.GetBrowserSubstance 191754 . 193701) (NC.ComputeBrowserSavedLinkingInfo 193703 . 194410) (
NC.ComputeBrowserSavedLinkingInfoForNode 194412 . 194852)) (194855 196747 (NC.FetchBrowserRootsInfo 
194865 . 195134) (NC.FetchBrowserLinkLabels 195136 . 195403) (NC.FetchBrowserFormat 195405 . 195659) (
NC.FetchSpecialBrowserSpecs 195661 . 195934) (NC.FetchBrowserDepth 195936 . 196187) (
NC.FetchBrowserSavedLinkingInfo 196189 . 196469) (NC.FetchBrowserLinksLegend 196471 . 196745)) (196748
 198764 (NC.SetBrowserRootsInfo 196758 . 197031) (NC.SetBrowserLinkLabels 197033 . 197301) (
NC.SetBrowserFormat 197303 . 197554) (NC.SetSpecialBrowserSpecs 197556 . 197840) (NC.SetBrowserDepth 
197842 . 198089) (NC.SetBrowserSavedLinkingInfo 198091 . 198476) (NC.SetBrowserLinksLegend 198478 . 
198762)) (198765 203904 (NC.ReadBrowserRootsInfo 198775 . 199574) (NC.ReadBrowserLinkLabels 199576 . 
199959) (NC.ReadBrowserFormat 199961 . 200335) (NC.ReadSpecialBrowserSpecs 200337 . 200724) (
NC.ReadBrowserDepth 200726 . 201390) (NC.ReadBrowserSavedLinkingInfo 201392 . 202285) (
NC.ReadBrowserSavedLinkingInfoForNode 202287 . 203523) (NC.ReadBrowserLinksLegend 203525 . 203902)) (
203905 207763 (NC.WriteBrowserRootsInfo 203915 . 204502) (NC.WriteBrowserLinkLabels 204504 . 204868) (
NC.WriteBrowserFormat 204870 . 205219) (NC.WriteSpecialBrowserSpecs 205221 . 205587) (
NC.WriteBrowserDepth 205589 . 205927) (NC.WriteBrowserSavedLinkingInfo 205929 . 206523) (
NC.WriteBrowserSavedLinkingInfoForNode 206525 . 207402) (NC.WriteBrowserLinksLegend 207404 . 207761)) 
(207764 217072 (NC.GraphLinkIconUpdateCheck 207774 . 208863) (NC.BrowserRepaintFn 208865 . 209235) (
NC.CoerceToGraphNodeID 209237 . 209879) (NC.CoerceToGraphNodeIDOrLabel 209881 . 210406) (
NC.GetBrowserNodeID 210408 . 211154) (NC.MakeBrowserNodeUID 211156 . 211371) (NC.GetBrowserHashArray 
211373 . 212450) (NC.RemoveBrowserNodeHashArrayEntry 212452 . 212823) (NC.HashArrayFromBrowserCard 
212825 . 213094) (NC.CardFromBrowserNodeID 213096 . 213463) (NC.SmashGraphNodeIDProps 213465 . 214074)
 (NC.PutBrowserSubstance 214076 . 215964) (NC.FetchBrowserRoots 215966 . 216426) (NC.SetBrowserRoots 
216428 . 217070)) (217073 218145 (NC.GraphNodeIDGetProp 217083 . 217431) (NC.GraphNodeIDPutProp 217433
 . 217793) (NC.GraphNodeIDRemProp 217795 . 218143)) (218512 221384 (NC.AddBrowserCard 218522 . 221382)
) (221405 221867 (NCAddStub.BrowserCard 221415 . 221865)))))
STOP