(FILECREATED "26-May-86 23:39:07" {QV}<NOTECARDS>1.3K>FGHDEVICE.;31 72784  

      changes to:  (VARS FGHDEVICECOMS)
		   (FNS NC.CloseDatabaseFile NC.CloseNoteFile NCLocalDevice.PutHashArray 
			NC.CheckpointNoteFile NCLocalDevice.PutIndexEntry 
			NCLocalDevice.PutNoteFileHeader NCLocalDevice.CheckpointNoteFile 
			NCLocalDevice.NoteFileOpenP NCLocalDevice.CloseNoteFile 
			NCLocalDevice.NoteFileOpenPFn NC.OpenNoteFile NC.StoreNoteFileInHashArray 
			NCLocalDevice.ReadIndexEntry NCLocalDevice.GetHashArray 
			NCLocalDevice.ConvertNoteFileFormat NC.ProcessNoteFileNeedsConversionError 
			NC.AskUserAboutTruncation NC.ProcessTruncationRequest 
			NC.ProcessNoteFileNeedsTruncationError NCLocalDevice.TruncateNoteFile 
			NCLocalDevice.SaveInformationPastCheckpoint NC.ProcessInspectAndRepairRequest 
			NC.OpenDatabaseFile NC.CreateNoteFile NC.ProcessNoteFileNotFoundError 
			NC.InstallCriticalUIDsInNoteFile NCLocalDevice.OpenNoteFile 
			NCLocalDevice.GetSpecialCardUIDs NCLocalDevice.BuildHashArray 
			NC.InstallDeviceVectorInNoteFile NC.LocalDeviceGetNoteFileHeader 
			NCLocalDevice.GetNoteFileHeader NCLocalDevice.NoteFileVersionOkayP 
			NCLocalDevice.PlausibleNoteFileHeaderP NCLocalDevice.CurrentVersion 
			NCLocalDevice.NoteFileNeedsTruncationP NCLocalDevice.OpenFailed 
			NC.LocalDeviceOpenNoteFile)
		   (RECORDS NoteFileDevice NoteFile NoteFileObject NoteFileCriticalUIDs)

      previous date: "23-May-86 00:35:05" {QV}<NOTECARDS>1.3K>FGHDEVICE.;1)


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

(PRETTYCOMPRINT FGHDEVICECOMS)

(RPAQQ FGHDEVICECOMS ((FNS NC.AskUserAboutTruncation NC.OpenDatabaseFile NC.OpenNoteFile 
			     NC.CreateNoteFile NC.InstallDeviceVectorInNoteFile 
			     NC.InstallCriticalUIDsInNoteFile NC.StoreNoteFileInHashArray 
			     NC.ProcessInspectAndRepairRequest NC.ProcessNoteFileNotFoundError 
			     NC.ProcessTruncationRequest NC.ProcessNoteFileNeedsConversionError 
			     NC.ProcessNoteFileNeedsTruncationError)
	(FNS NC.CloseDatabaseFile NC.CloseNoteFile NC.CheckpointNoteFile)
	(RECORDS NoteFileCriticalUIDs NoteFileDevice NoteFile)
	(VARS (NC.DeviceVectorsHashArray (HASHARRAY 10)))
	(P (PUTHASH (QUOTE LOCALSINGLEUSER)
		    (create NoteFileDevice OpenNoteFileFn ← (FUNCTION NCLocalDevice.OpenNoteFile)
			    CloseNoteFileFn ← (FUNCTION NCLocalDevice.CloseNoteFile)
			    BuildHashArrayFn ← (FUNCTION NCLocalDevice.BuildHashArray)
			    NoteFileOpenPFn ← (FUNCTION NCLocalDevice.NoteFileOpenP)
			    CheckpointNoteFileFn ← (FUNCTION NCLocalDevice.CheckpointNoteFile)
			    ConvertNoteFileFormatFn ← (FUNCTION NCLocalDevice.ConvertNoteFileFormat)
			    TruncateNoteFileFn ← (FUNCTION NCLocalDevice.TruncateNoteFile))
		    NC.DeviceVectorsHashArray))
	(* * Stuff for local device notefiles)
	(FNS NCLocalDevice.OpenNoteFile NCLocalDevice.BuildHashArray NCLocalDevice.GetNoteFileHeader 
	     NCLocalDevice.NoteFileVersionOkayP NCLocalDevice.PlausibleNoteFileHeaderP 
	     NCLocalDevice.CurrentVersion NCLocalDevice.NoteFileNeedsTruncationP 
	     NCLocalDevice.GetSpecialCardUIDs NCLocalDevice.OpenFailed NCLocalDevice.ReadIndexEntry 
	     NCLocalDevice.GetHashArray NCLocalDevice.SaveInformationPastCheckpoint 
	     NCLocalDevice.TruncateNoteFile NCLocalDevice.ConvertNoteFileFormat)
	(FNS NCLocalDevice.NoteFileOpenP NCLocalDevice.CloseNoteFile NCLocalDevice.CheckpointNoteFile 
	     NCLocalDevice.PutHashArray NCLocalDevice.PutIndexEntry NCLocalDevice.PutNoteFileHeader)
	(RECORDS NoteFileVersion)
	(VARS (NC.OpenLocalNoteFilesPublicOrPrivate (QUOTE PRIVATE))
	      (NCLocalDevice.CurrentNoteFileVersionNumber 3)
	      (NCLocalDevice.NoteFileVersionsList (LIST (create NoteFileVersion Version ← 3 
								NumberOfReservedCards ← 20 
								NoteFileIndexWidth ← 28 
								NoteFileHeaderSize ← 30))))))
(DEFINEQ

(NC.AskUserAboutTruncation
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 16:46")

          (* * Ask the user what to do since NoteFile truncation is needed.)



          (* * fgh 5/25/86 First created.)


    (LET (Items)

          (* * List user's options. Include Inspect&Repair only if this NoteFIle device has a RepairFn.)


         (SETQ Items (BQUOTE ((Abort (QUOTE Abort)
					 "Abort the Open.")
				  (Truncate% File (QUOTE Truncate% File)
						  
				 "Truncate the file throwing away changes since last checkpoint.")
				  ,@(if (fetch (NoteFile RepairNoteFileFn) of NoteFile)
					then (LIST (QUOTE (Inspect% &% Repair (QUOTE 
									       Inspect% &% Repair)
										    
							   "Run Inspect&Repair on this NoteFile.")))))
				 ))

          (* * Bring up the menu with the options.)


         (MENU (create MENU
			   ITEMS ← Items
			   MENUOUTLINESIZE ← 2
			   MENUFONT ←(FONTCREATE (QUOTE HELVETICA)
						   12
						   (QUOTE BOLD)))
		 (if (WINDOWP PromptWindow)
		     then (create POSITION
				      XCOORD ←(fetch (POSITION XCOORD) of (SETQ PromptWinPos
										  (WINDOWPOSITION
										    PromptWindow)))
				      YCOORD ←(DIFFERENCE (fetch (POSITION YCOORD)
							       of PromptWinPos)
							    (fetch (MENU IMAGEHEIGHT)
							       of Menu)))
		   else NIL)))))

(NC.OpenDatabaseFile
  (LAMBDA (NoteFileOrFileName Access Don'tCacheTypesAndTitlesFlg QuietFlg Don'tCreateFlg 
			      Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg 
			      Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg InterestedWindow)
                                                             (* fgh: "25-May-86 13:15")
    (NC.OpenNoteFile NoteFileOrFileName NC.NoteFilesHashArray Don'tCacheTypesAndTitlesFlg 
		       Don'tCreateFlg Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg 
		       Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg InterestedWindow)))

(NC.OpenNoteFile
  (LAMBDA (NoteFileOrFileName NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
			      Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg 
			      Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg PromptWindow 
			      PublicOrPrivate)               (* fgh: "26-May-86 11:47")

          (* * fgh 5/23/86 Renamed to NC.OpenNoteFile from NC.OpenDatabaseFile. Total revamp to implement device vector.)



          (* * Temp prompt window hack for testing)


    (OR PromptWindow (SETQ PromptWindow PROMPTWINDOW))

          (* * If the value returned is not a NoteFile, let the user know there's been some problem.)


    (PROG (NoteFile FileName ReturnValue CriticalUIDs)

          (* * Figure out the name of the file containing the NoteFile)


	    (if (NULL (SETQ FileName (COND
			      ((type? NoteFile NoteFileOrFileName)
				(fetch (NoteFile FullFileName) of NoteFileOrFileName))
			      (NoteFileOrFileName)
			      (T (NC.DatabaseFileName "Name of NoteFile to open:" " -- " T NIL NIL 
							PromptWindow)))))
		then (RETURN))
	    (SETQ FileName (OR (FULLNAME FileName)
				   FileName))

          (* * Notify user.)


	    (if PromptWindow
		then (NC.PrintMsg PromptWindow T "Opening NoteFile: " FileName " ..."
				      (CHARACTER 13)))

          (* * Create a NoteFile object)


	    (SETQ NoteFile (if (type? NoteFile NoteFileOrFileName)
				 then NoteFileOrFileName
			       else (create NoteFile)))
	    (replace (NoteFile FullFileName) of NoteFile with FileName)

          (* * Figure out the appropriate device vector from the file name.)


	    (NC.InstallDeviceVectorInNoteFile NoteFile PublicOrPrivate)

          (* * Run through OpenNoteFileFns with param of BEFORE. Exit if any returns DON'T)


	    (if (for Function in NC.OpenNoteFileFns thereis
							   (OR (EQ Function (QUOTE DON'T))
								 (EQ (QUOTE DON'T)
								       (APPLY* Function Name 
										 NoteFile
										 (QUOTE BEFORE)))))
		then (if (WINDOWP PromptWindow)
			   then (NC.PrintMsg PromptWindow NIL "Open aborted for NoteFile " 
						 FileName "." (CHARACTER 13)))
		       (RETURN))

          (* * Call the device specific OpenNoteFileFn, which returns a list of special UIDs)


	    (if (NULL (ERSETQ (SETQ ReturnValue (APPLY* (fetch (NoteFile OpenNoteFileFn)
								     of NoteFile)
								  NoteFile PromptWindow))))
		then (SETQ ReturnValue (QUOTE NoteFileOpenFailed)))

          (* * Process error returns from the OpenNoteFileFn)


	    (if (NOT (LITATOM ReturnValue))
		then 

          (* * OpenNoteFileFn returned correctly)


		       (SETQ CriticalUIDs ReturnValue)
	      else 

          (* * Error, process it.)


		     (SETQ ReturnValue
		       (OR (SELECTQ ReturnValue
					(NoteFileNotFound (NC.ProcessNoteFileNotFoundError NoteFile 
									       NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
										   Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
										 Don'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
										     PromptWindow 
										  PublicOrPrivate))
					(NoteFileNeedsConversion (
							   NC.ProcessNoteFileNeedsConversionError
								   NoteFile NoteFilesHashArray 
								   Don'tCacheTypesAndTitlesFlg 
								   Don'tCreateFlg 
								   Convertw/oConfirmFlg 
								   Don'tCreateArrayFlg 
								   Don'tTruncateFlg 
								   Don'tCreateInterfaceFlg 
								   Don'tGetSpecialCardsFlg 
								   PromptWindow PublicOrPrivate))
					(NoteFileNeedsTruncation (
							   NC.ProcessNoteFileNeedsTruncationError
								   NoteFile NoteFilesHashArray 
								   Don'tCacheTypesAndTitlesFlg 
								   Don'tCreateFlg 
								   Convertw/oConfirmFlg 
								   Don'tCreateArrayFlg 
								   Don'tTruncateFlg 
								   Don'tCreateInterfaceFlg 
								   Don'tGetSpecialCardsFlg 
								   PromptWindow PublicOrPrivate))
					(NoteFileAlreadyOpen
					  (ERSETQ (NC.ReportError NIL (CONCAT
									(fetch (NoteFile 
										     FullFileName)
									   of NoteFile)
									
					    " is already open for exclusive access. Open failed."))))
					(NoteFileOpenFailed (ERSETQ
							      (NC.ReportError
								NIL
								(CONCAT "Open of "
									  (fetch (NoteFile 
										     FullFileName)
									     of NoteFile)
									  
								    " failed for unknown reason."))))
					(NoteFileHeaderBad (ERSETQ
							     (NC.ReportError
							       NIL
							       (CONCAT "Header of NoteFile "
									 (fetch (NoteFile 
										     FullFileName)
									    of NoteFile)
									 
							  " is bad.  Contact a NoteCards wizard."))))
					(PROGN (ERSETQ (NC.ReportError NIL
									     (CONCAT 
									   "Unknown error code ("
										       ReturnValue 
						     ") returned by OpenNoteFileFn for NoteFile "
										       FileName)))))
			     ReturnValue))

          (* * notify the user. if there's been a problem)


		     (if (AND (NOT (type? NoteFile ReturnValue))
				  (WINDOWP PromptWindow))
			 then (NC.PrintMsg PromptWindow NIL "Open aborted for NoteFile " FileName 
					       "."
					       (CHARACTER 13)))

          (* * return whatever the error processing returned.)


		     (RETURN ReturnValue))
	    (SETQ ReturnValue)

          (* * If needed, build a hash array by calling the device specific BuilHashArrayFn.)


	    (if (NOT Don'tCreateArrayFlg)
		then (if PromptWindow
			   then (NC.PrintMsg PromptWindow T "Opening NoteFile: " FileName
						 (CHARACTER 13)
						 "Building hash array ..."
						 (CHARACTER 13)))
		       (if (OR (NULL (ERSETQ (SETQ ReturnValue (APPLY*
							 (fetch (NoteFile BuildHashArrayFn)
							    of NoteFile)
							 NoteFile PromptWindow))))
				   (NOT (type? NoteFile ReturnValue)))
			   then 

          (* * Error during building of hash array)


				  (ERSETQ (NC.ReportError NIL (CONCAT 
							  "Build Hash Array failed for NoteFile "
									    (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
									    " because " ReturnValue)))
				  (RETURN)))

          (* * Set up critical UIDs in NoteFile object using the values returned from OpenNoteFileFn.)


	    (NC.InstallCriticalUIDsInNoteFile NoteFile CriticalUIDs)

          (* * Store this NoteFile object in the appropriate NoteFile hash array)


	    (NC.StoreNoteFileInHashArray NoteFile NoteFilesHashArray)

          (* * if needed, cache the special cards)


	    (if (NOT Don'tGetSpecialCardsFlg)
		then (if PromptWindow
			   then (NC.PrintMsg PromptWindow T "Opening NoteFile: " FileName
						 (CHARACTER 13)
						 "Caching top level FileBoxes ..."
						 (CHARACTER 13)))
		       (NC.GetSpecialCards NoteFile QuietFlg))

          (* * If needed, start the titles and types caching process)


	    (if (NOT Don'tCacheTypesAndTitlesFlg)
		then (replace (NoteFile CachingProcess) of NoteFile
			  with (ADD.PROCESS (LIST (FUNCTION NC.CacheTypesAndTitles)
							NoteFile))))

          (* * If needed, open up a NoteFile interface.)


	    (if (NOT Don'tCreateInterfaceFlg)
		then (NC.SetUpNoteFileInterface NoteFile))

          (* * Record this as the last NF opened.)


	    (SETQ NC.LastNoteFileOpened NoteFile)

          (* * Run through OpenNoteFIleFns with param of AFTER. Stop if any returns DON'T)


	    (for Function in NC.OpenNoteFileFns thereis (EQ (QUOTE DON'T)
								    (APPLY* Function Name NoteFile
									      (QUOTE AFTER))))

          (* * Go home, returning NoteFile)


	    (if PromptWindow
		then (NC.PrintMsg PromptWindow T "Opening NoteFile: " FileName (CHARACTER
					13)
				      "Done."
				      (CHARACTER 13)))
	    (RETURN NoteFile))))

(NC.CreateNoteFile
  (LAMBDA (NoteFileName PromptWindow)                        (* fgh: "25-May-86 13:27")

          (* * Kludge for now)


    (fetch (NoteFile FullFileName) of (NC.CreateDatabaseFile NoteFileName NIL NIL NIL NIL NIL 
								   PromptWindow))))

(NC.InstallDeviceVectorInNoteFile
  (LAMBDA (NoteFile PublicOrPrivate)                         (* fgh: "23-May-86 14:46")

          (* * Figure out the appropriate device vector for NoteFile from its FullName and install in the device vector 
	  slot.)



          (* * fgh 5/23/86 First created.)


    (LET (NSAddress Host)

          (* * Get the HOST filed of the NoteFIle file name.)


         (SETQ Host (FILENAMEFIELD (fetch (NoteFile FullFileName) of NoteFile)
				       (QUOTE HOST)))

          (* * If Host is an NS Server that responds to NoteCards AreYouThere msg, then use the Server device.
	  Else use a local single or multiu user device.)


         (if (AND (SETQ NSAddress (LOOKUP.NS.SERVER Host))
		      (NCCLIENT.AREYOUTHERE NSAddress))
	     then (replace (NoteFile Device) of NoteFile with (GETHASH (QUOTE SERVER)
										 
									NC.DeviceVectorsHashArray))
	   elseif (OR (AND PublicOrPrivate (EQ PublicOrPrivate (QUOTE PRIVATE)))
			  (AND (NULL PublicOrPrivate)
				 (EQ NC.OpenLocalNoteFilesPublicOrPrivate (QUOTE PRIVATE))))
	     then (replace (NoteFile Device) of NoteFile with (GETHASH (QUOTE 
										  LOCALSINGLEUSER)
										 
									NC.DeviceVectorsHashArray))
	   else (replace (NoteFile Device) of NoteFile with (GETHASH (QUOTE 
										   LOCALMULTIUSER)
									       
									NC.DeviceVectorsHashArray)))))
)

(NC.InstallCriticalUIDsInNoteFile
  (LAMBDA (NoteFile CriticalUIDs)                            (* fgh: "24-May-86 12:23")

          (* * Install the contents of the critical UIDs record into the NoteFile object.)


    (LET ((HashArray (HARRAYP (fetch (NoteFile HashArray) of NoteFile))))
         (if (NOT (NC.SameUIDP (fetch (NoteFile UID) of NoteFile)
				     (fetch (NoteFileCriticalUIDs NoteFile) of CriticalUIDs)))
	     then (ERSETQ (NC.ReportError NIL "Mismatch in NoteFile UIDs."))
	   else (replace (NoteFile TableOfContentsCard) of NoteFile
		     with (if HashArray
				then (NC.CardFromUID (fetch (NoteFileCriticalUIDs 
										  TableOfContents)
							    of CriticalUIDs)
							 NoteFile)
			      else (create Card
					       UID ←(fetch (NoteFileCriticalUIDs TableOfContents)
						       of CriticalUIDs))))
		  (replace (NoteFile OrphansCard) of NoteFile
		     with (if HashArray
				then (NC.CardFromUID (fetch (NoteFileCriticalUIDs Orphans)
							    of CriticalUIDs)
							 NoteFile)
			      else (create Card
					       UID ←(fetch (NoteFileCriticalUIDs Orphans)
						       of CriticalUIDs))))
		  (replace (NoteFile ToBeFiledCard) of NoteFile
		     with (if HashArray
				then (NC.CardFromUID (fetch (NoteFileCriticalUIDs ToBeFiled)
							    of CriticalUIDs)
							 NoteFile)
			      else (create Card
					       UID ←(fetch (NoteFileCriticalUIDs ToBeFiled)
						       of CriticalUIDs))))
		  (replace (NoteFile LinkLabelsCard) of NoteFile
		     with (if HashArray
				then (NC.CardFromUID (fetch (NoteFileCriticalUIDs LinkLabels)
							    of CriticalUIDs)
							 NoteFile)
			      else (create Card
					       UID ←(fetch (NoteFileCriticalUIDs LinkLabels)
						       of CriticalUIDs))))
		  (replace (NoteFile RegistryCard) of NoteFile
		     with (if HashArray
				then (NC.CardFromUID (fetch (NoteFileCriticalUIDs Registry)
							    of CriticalUIDs)
							 NoteFile)
			      else (create Card
					       UID ←(fetch (NoteFileCriticalUIDs Registry)
						       of CriticalUIDs))))))))

(NC.StoreNoteFileInHashArray
  (LAMBDA (NoteFile HashArray)                               (* fgh: "26-May-86 11:42")

          (* * store NoteFile in HashArray, a NoteFiles hash array.)



          (* * fgh 5/23/86 First created.)



          (* * Are there any other NoteFiles of the same fullfilename here? If so, something got messed up.
	  Remove these items.)


    (MAPHASH HashArray (FUNCTION (LAMBDA (NF UID)
		   (if (EQ (fetch (NoteFile FullFileName) of NoteFile)
			       (fetch (NoteFile FullFileName) of NF))
		       then (PUTHASH UID NIL HashArray)))))

          (* * Okay, now put in the new entry)


    (PUTHASH (fetch (NoteFile UID) of NoteFile)
	       NoteFile HashArray)))

(NC.ProcessInspectAndRepairRequest
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
                                                             (* fgh: "25-May-86 14:49")

          (* * Do an an InspectAndRepair on a file then try to reopen. Used when checkpoint pinter out of sorts during an 
	  Open.)



          (* * fgh 5/25/86 First created.)


    (if (CAR (ERSETQ (NC.RepairNoteFile NoteFile)))
	then 

          (* * Repair NoteFile succeeded, try to Open the NF now.)


	       (NC.OpenNoteFile NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg 
				  Don'tCreateFlg Convertw/oConfirmFlg Don'tCreateArrayFlg 
				  Don'tTruncateFlg Don'tCreateInterfaceFlg Don'tGetSpecialCardsFlg 
				  PromptWindow PublicOrPrivate)
      else 

          (* * REapir NoteFile failed for some reason. Report and return.)


	     (ERSETQ (NC.ReportError NIL (CONCAT "NoteFile Inspect&RepairFailed for NoteFile "
						       (fetch (NoteFile FullFileName) of NoteFile)
						       )))
	     (QUOTE InspectAndRepairFailed))))

(NC.ProcessNoteFileNotFoundError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
                                                             (* fgh: "25-May-86 13:14")

          (* * NoteFile couldnot be found when an attempt was made to open it. Find out if the user wants to create it.)



          (* * fgh 5/23/86 First created.)


    (if (NULL (WINDOWP PromptWindow))
	then 

          (* * If QuietFlg is set, then we'll just have to send back a error notification.)


	       (QUOTE NoteFileNotFound)
      else 

          (* * Otherwise, we can interact with the user.)


	     (LET (NewFileName)

          (* * Notify user of the error)


	          (NC.PrintMsg PromptWindow T "Could not find NoteFile " (fetch (NoteFile 
										     FullFileName)
									      of NoteFile)
				 (CHARACTER 13))

          (* * If the user wants to create the file, then create it and try the open again.)


	          (if (AND (NULL Don'tCreateFlg)
			       (NC.AskYesOrNo (CONCAT "Do you want to create "
							  (fetch (NoteFile FullFileName)
							     of NoteFile))
						" -- " "Y" NIL PromptWindow T NIL))
		      then (if (AND (ERSETQ (SETQ NewFileName (NC.CreateNoteFile
							(fetch (NoteFile FullFileName)
							   of NoteFile)
							PromptWindow)))
					  NewFileName)
				 then (replace (NoteFile FullFileName) of NoteFile
					   with NewFileName)
					(NC.OpenNoteFile NoteFile NoteFilesHashArray 
							   Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
							   Convertw/oConfirmFlg Don'tCreateArrayFlg 
							   Don'tTruncateFlg Don'tCreateInterfaceFlg 
							   Don'tGetSpecialCardsFlg PromptWindow 
							   PublicOrPrivate))
		    else (QUOTE NoteFileNotFound))))))

(NC.ProcessTruncationRequest
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
                                                             (* fgh: "25-May-86 17:07")

          (* * Do the actual truncation of a NoteFile that has stuf past the checkpoint pointer.)



          (* * fgh 5/25/86 First created.)


    (LET (ReturnValue (TruncationFn (fetch (NoteFile TruncateNoteFileFn) of NoteFile)))

          (* * Do the truncation.)


         (if (type? NoteFile (CAR (ERSETQ (SETQ ReturnValue (APPLY* TruncationFn NoteFile)
						    ))))
	     then 

          (* * Truncation successful, Open the note file.)


		    (NC.OpenNoteFile NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg 
				       Don'tCreateFlg Convertw/oConfirmFlg Don'tCreateArrayFlg 
				       Don'tTruncateFlg Don'tCreateInterfaceFlg 
				       Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
	   else 

          (* * Error during truncation fn. report and get out of here.)


		  (SELECTQ ReturnValue
			     (NoteFileTruncationAborted (QUOTE NoteFileTruncationAborted))
			     (PROGN (ERSETQ (NC.ReportError NIL (CONCAT 
						       "NoteFile truncation failed for NoteFile "
										(fetch
										  (NoteFile 
										     FullFileName)
										   of NoteFile)
										" because " 
										ReturnValue ".")))
				      (QUOTE NoteFileTruncationFailed)))))))

(NC.ProcessNoteFileNeedsConversionError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
                                                             (* fgh: "25-May-86 17:21")

          (* * Discovered NoteFile needs version conversion when attempted to open it. Process that error.)



          (* * fgh 5/23/86 First created.)


    (LET (ConversionFn ReturnValue)

          (* * If appropriate, notify the user.)


         (if (WINDOWP PromptWindow)
	     then (NC.PrintMsg PromptWindow T "NoteFile " (fetch (NoteFile FullFileName)
								 of NoteFile)
				   "is an old format file."
				   (CHARACTER 13)))

          (* * If the device has a ConversionFn, then apply it and try to Open the NoteFile.)


         (if (SETQ ConversionFn (fetch (NoteFile ConvertNoteFileFormatFn) of NoteFile))
	     then 

          (* * ask the user if conversion should be done. If so, do it, else return an error msg,)


		    (if (OR Convertw/oConfirmFlg (NC.AskYesOrNo 
						  "Do you want to convert it to the new format? "
								      " -- " "Y" NIL PromptWindow))
			then 

          (* * go ahead and convert.)


			       (if (type? NoteFile (CAR (ERSETQ (SETQ ReturnValue
									  (APPLY* ConversionFn 
										    NoteFile)))))
				   then 

          (* * Conversion successful, Open the note file.)


					  (NC.OpenNoteFile NoteFile NoteFilesHashArray 
							     Don'tCacheTypesAndTitlesFlg 
							     Don'tCreateFlg Convertw/oConfirmFlg 
							     Don'tCreateArrayFlg Don'tTruncateFlg 
							     Don'tCreateInterfaceFlg 
							     Don'tGetSpecialCardsFlg PromptWindow 
							     PublicOrPrivate)
				 else 

          (* * Error during conversion fn. report and get out of here.)


					(SELECTQ ReturnValue
						   (PROGN (ERSETQ
							      (NC.ReportError
								NIL
								(CONCAT 
						"NoteFile format conversion failed for NoteFile "
									  (fetch (NoteFile 
										     FullFileName)
									     of NoteFile))))
							    (QUOTE NoteFileConversionFailed))))
		      else 

          (* * User said don't convert. Just return)


			     (QUOTE NoteFileNeedsConversion))
	   else 

          (* * No conversion fn. Tell the user if appropriate and return an error msg.)


		  (if (WINDOWP PromptWindow)
		      then (NC.PrintMsg PromptWindow NIL "No format conversion possible."
					    (CHARACTER 13)
					    "See a NoteCards wizard."
					    (CHARACTER 13)))
		  (QUOTE NoteFileNeedsConversion)))))

(NC.ProcessNoteFileNeedsTruncationError
  (LAMBDA (NoteFile NoteFilesHashArray Don'tCacheTypesAndTitlesFlg Don'tCreateFlg 
		    Convertw/oConfirmFlg Don'tCreateArrayFlg Don'tTruncateFlg Don'tCreateInterfaceFlg 
		    Don'tGetSpecialCardsFlg PromptWindow PublicOrPrivate)
                                                             (* fgh: "25-May-86 17:07")

          (* * Discovered NoteFile needs version truncation when attempted to open it. Process that error.)



          (* * fgh 5/23/86 First created.)


    (PROG (TruncationFn)

          (* * If appropriate, notify the user.)


	    (if (WINDOWP PromptWindow)
		then (NC.PrintMsg PromptWindow T "NoteFile " (fetch (NoteFile FullFileName)
								    of NoteFile)
				      
			    " has information written since last successful close or checkpoint."
				      (CHARACTER 13)))

          (* * If the device has a TruncationFn then apply it and try to Open the NoteFile.)


	    (if (AND (NULL Don'tTruncateFlg)
			 (SETQ TruncationFn (fetch (NoteFile TruncateNoteFileFn) of NoteFile)))
		then 

          (* * ASk the user if they want to truncate, or abort, or repair the notefile.)


		       (SELECTQ (NC.AskUserAboutTruncation NoteFile PromptWindow)
				  (Abort (RETURN (QUOTE NoteFileNeedsTruncation)))
				  (Inspect% &% Repair (RETURN (NC.ProcessInspectAndRepairRequest
								  NoteFile NoteFilesHashArray 
								  Don'tCacheTypesAndTitlesFlg 
								  Don'tCreateFlg Convertw/oConfirmFlg 
								  Don'tCreateArrayFlg 
								  Don'tTruncateFlg 
								  Don'tCreateInterfaceFlg 
								  Don'tGetSpecialCardsFlg 
								  PromptWindow PublicOrPrivate)))
				  (Truncate% File (RETURN (NC.ProcessTruncationRequest NoteFile 
									       NoteFilesHashArray 
								      Don'tCacheTypesAndTitlesFlg 
										   Don'tCreateFlg 
									     Convertw/oConfirmFlg 
									      Don'tCreateArrayFlg 
										 Don'tTruncateFlg 
									  Don'tCreateInterfaceFlg 
									  Don'tGetSpecialCardsFlg 
										     PromptWindow 
										  PublicOrPrivate)))
				  (RETURN (QUOTE NoteFileNeedsTruncation)))
	      else 

          (* * No TruncationFn. Tell the user if appropriate and return an error msg.)


		     (if (WINDOWP PromptWindow)
			 then (NC.PrintMsg PromptWindow NIL 
					       "No file truncation possible for this NoteFile."
					       (CHARACTER 13)
					       "See a NoteCards wizard."
					       (CHARACTER 13)))
		     (RETURN (QUOTE NoteFileNeedsTruncation))))))
)
(DEFINEQ

(NC.CloseDatabaseFile
  (LAMBDA (NoteFile)                                         (* fgh: "26-May-86 23:24")
    (NC.CloseNoteFile NoteFile PROMPTWINDOW)))

(NC.CloseNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "26-May-86 23:37")

          (* * Close a NoteFIle)



          (* * rht 10/23/84: Now gives user option of closing and saving all open cards on the screen.)



          (* * rht 11/8/84: Put RESETLST around NC.CacheTitles call.)



          (* * rht 1/9/85: Clear the NC.UncachingNotCompleted variable when close successfully completes.)



          (* * rht 1/31/85: Added call to checkpoint database. That in turn dumps the next nodeID and next linkID.)



          (* * rht 7/14/85: Replaced the call to reset the main menu with call to NC.ResetMainMenu. Also took out redundant 
	  reset of PSA.Database, since NC.ForceDatabaseClose is doing that.)



          (* * fgh 10/16/85 removed call to CacheTypesAndTitles because uncacheing now done automatically by cache 
	  mechanism.)



          (* * fkr 10/29/85: Now kills caching process from database streamprop.)



          (* * fkr 11/8/85 Updated to handle new NoteFile object and new CardID scheme.)



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



          (* * rht 3/26/86: Now searches for active cards over whole notefile not just among cards up on screen.
	  Uses NC.MapCards.)



          (* * kirk 28Apr86 Now returns NoteFile if successful.)



          (* * fgh 5/2/86 Cleaned up. Ask user to confirm only if there are cards on the screen, not if there are active, but
	  not displayed ones. Added calls to the NC.CloseNoteFileFns before and after the closeing.)



          (* * fgh 5/26/86 Revamp for device vector implementation.)


    (if (NOT (WINDOWP PromptWindow))
	then (SETQ PromptWindow NIL))
    (PROG (CardTotal ActiveCards ReturnValue)

          (* * Make sure NF is open)


	    (if (NULL (ERSETQ (SETQ ReturnValue (APPLY* (fetch (NoteFile NoteFileOpenPFn)
								     of NoteFile)
								  NoteFile))))
		then (SETQ ReturnValue (QUOTE OpenPFailed)))
	    (if (NULL ReturnValue)
		then 

          (* * NoteFile is not open.)


		       (if PromptWindow
			   then (NC.PrintMsg PromptWindow T (fetch (NoteFile FullFileName)
								   of NoteFile)
						 " is not an open NoteFile!!!"
						 (CHARACTER 13)))
		       (RETURN NIL)
	      elseif (NOT (type? NoteFile ReturnValue))
		then 

          (* * Error return from NoteFileOpenPFn)


		       (if (NULL (ERSETQ (NC.ReportError NIL (CONCAT "OpenP test on "
									       (fetch (NoteFile
											  
										     FullFileName)
										  of NoteFile)
									       "failed because " 
									       ReturnValue
									       (CHARACTER 13)
									       
							"OK to continue Close. ↑ to abort Close."))))
			   then (RETURN ReturnValue)))

          (* * If there is PromptWindow, then look for cards on the screen. If there are active cards ask the user if they 
	  still want to close. When there's no PromptWindow, we just close the active cards.)


	    (if (AND PromptWindow (for Window in (OPENWINDOWS)
					 thereis (LET (Card)
						        (AND (SETQ Card (NC.CardFromWindow
								   Window))
							       (NC.SameNoteFileP
								 NoteFile
								 (fetch (Card NoteFile)
								    of Card)))))
			 (NULL (NC.AskYesOrNo (CONCAT 
					"There are still cards on the screen from this NoteFile "
							    (fetch (NoteFile FullFileName)
							       of NoteFile)
							    "."
							    (CHARACTER 13)
							    "Want to close and save them? ")
						  " -- "
						  (QUOTE Yes)
						  NIL PromptWindow NIL NIL)))
		then (RETURN NIL))

          (* * Run through CloseNoteFileFns with param of BEFORE. Exit if any returns DON'T)


	    (if (for Function in NC.CloseNoteFileFns thereis
							    (OR (EQ Function (QUOTE DON'T))
								  (EQ (QUOTE DON'T)
									(APPLY* Function NoteFile
										  (QUOTE BEFORE)))))
		then (RETURN NIL))

          (* * Close all the active cards)


	    (if (SETQ ActiveCards (NC.MapCards NoteFile (FUNCTION (LAMBDA (Card)
							 Card))
						     (FUNCTION NC.ActiveCardP)))
		then (if PromptWindow
			   then (NC.PrintMsg PromptWindow T 
						 "Closing and saving active cards ... "))
		       (RESETLST (RESETSAVE NC.ForceSourcesFlg NIL)
				   (RESETSAVE NC.ForceFilingFlg NIL)
				   (RESETSAVE NC.ForceTitlesFlg NIL)
				   (for Card in ActiveCards bind Window
				      do (NC.QuitCard Card T NIL T)
					   (if (SETQ Window (NC.FetchWindow Card))
					       then (bind (Process ←(WINDOWPROP Window
										      (QUOTE 
											  PROCESS)))
							 until (OR (NULL Process)
								       (PROCESS.FINISHEDP Process))
							 do (BLOCK)))))
		       (if PromptWindow
			   then (NC.PrintMsg NIL NIL "Done." (CHARACTER 13))))

          (* * Delete the types and titles caching process if still alive.)


	    (DEL.PROCESS (fetch (NoteFile CachingProcess) of NoteFile))

          (* * Checkpoint the NoteFile.)


	    (if PromptWindow
		then (NC.PrintMsg PromptWindow T "Closing Notefile ... " (CHARACTER 13)))
	    (if (NULL (CAR (ERSETQ (SETQ ReturnValue (NC.CheckpointNoteFile NoteFile 
										     PromptWindow)))))
		then (SETQ ReturnValue CheckpointFailed))

          (* * Process error returns from in NC.CheckpointNoteFile)


	    (if (NOT (type? NoteFile ReturnValue))
		then (if (NULL (ERSETQ (NC.ReportError NIL (CONCAT 
									"Checkpoint of NoteFile "
									       (fetch (NoteFile
											  
										     FullFileName)
										  of NoteFile)
									       " failed because " 
									       ReturnValue "."
									       (CHARACTER 13)
									       
							"OK to continue Close. ↑ to abort Close."))))
			   then (RETURN ReturnValue)))

          (* * Close the file.)


	    (if (NULL (CAR (ERSETQ (SETQ ReturnValue (APPLY* (fetch (NoteFile 
										  CloseNoteFileFn)
									    of NoteFile)
									 NoteFile PromptWindow)))))
		then (SETQ ReturnValue (QUOTE CloseFailed)))

          (* * Process error returns from the close.)


	    (if (NOT (type? NoteFile ReturnValue))
		then (SELECTQ ReturnValue
				  (NoteFileNotOpen
				    (if (NULL (ERSETQ (NC.ReportError
							      NIL
							      (CONCAT "NoteFile"
									(fetch (NoteFile 
										     FullFileName)
									   of NoteFile)
									" is not open."
									(CHARACTER 13)
									
							"OK to continue Close. ↑ to abort Close."))))
					then (RETURN ReturnValue)))
				  (PROGN (ERSETQ (NC.ReportError NIL
								       (CONCAT "Close of NoteFile "
										 (fetch
										   (NoteFile 
										     FullFileName)
										    of NoteFile)
										 " failed because " 
										 ReturnValue "."
										 (CHARACTER 13))))
					   (RETURN ReturnValue))))

          (* * Run through CloseNoteFileFns with param of AFTER. Stop if any returns DON'T)


	    (for Function in NC.CloseNoteFileFns thereis (EQ (QUOTE DON'T)
								     (APPLY* Function NoteFile
									       (QUOTE AFTER))))

          (* * Reset the interface and notify the user.)


	    (NC.ResetNoteFileInterface NoteFile)
	    (if PromptWindow
		then (NC.PrintMsg PromptWindow T (fetch (NoteFile FullFileName) of NoteFile)
				      " closed."))

          (* * * Cleanup a bit.)

                                                             (* Clean off the card cache's)
	    (ADD.PROCESS (LIST (FUNCTION NC.CleanupCardObjects)
				   (fetch (NoteFile HashArray) of NoteFile)))
                                                             (* Clean off the NoteFile object to remove any 
							     circularities.)
	    (create NoteFile smashing NoteFile UID ←(fetch (NoteFile UID) of NoteFile)
					  FullFileName ←(fetch (NoteFile FullFileName)
							   of NoteFile)
					  Menu ←(fetch (NoteFile Menu) of NoteFile)
					  NoteFileDevice ← NIL)

          (* * Return the NF)


	    (RETURN NoteFile))))

(NC.CheckpointNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "26-May-86 23:11")

          (* * Checkpoint a notefile by call the device specific checkpoint fn.)



          (* * fgh 5/26/86 First created.)


    (LET (ReturnValue)

          (* * If appropriate, msg the user.)


         (if (WINDOWP PromptWindow)
	     then (NC.PrintMsg PromptWindow T "Checkpointing notefile " (fetch (NoteFile 
										     FullFileName)
									       of NoteFile)
				   " ..."
				   (CHARACTER 13)))

          (* * Save the dirty cards on the screen)


         (NC.SaveDirtyCards NoteFile)

          (* * Call the device specific checkpoint fn.)


         (if (NULL (ERSETQ (SETQ ReturnValue (APPLY* (fetch (NoteFile 
									     CheckpointNoteFileFn)
								  of NoteFile)
							       NoteFile PromptWindow))))
	     then (SETQ ReturnValue (QUOTE CheckpointFailed)))

          (* * Process the error returns.)


         (if (type? NoteFile ReturnValue)
	     then 

          (* * Successful return.)


		    (if (WINDOWP PromptWindow)
			then (NC.PrintMsg PromptWindow T " Checkpoint done." (CHARACTER 13)))
		    NoteFile
	   else 

          (* * Error return.)


		  (ERSETQ (NC.ReportError NIL (CONCAT "Checkpoint failed for "
							    (fetch (NoteFile FullFileName)
							       of NoteFile)
							    " because " ReturnValue ".")))
		  ReturnValue))))
)
[DECLARE: EVAL@COMPILE 

(RECORD NoteFileCriticalUIDs (NoteFile TableOfContents Orphans ToBeFiled LinkLabels Registry))

(DATATYPE NoteFileDevice (ListNoteFilesFn CreateNoteFileFn DeleteNoteFileFn OpenNoteFileFn 
					    BuildHashArrayFn CloseNoteFileFn NoteFileOpenPFn 
					    CheckpointNoteFileFn NewCardUIDFn MarkCardDeletedFn 
					    PutCardPartFn GetCardPartFn ObtainWritePermissionFn 
					    ReleaseWritePermissionFn CancelCacheSubscriptionFn 
					    RepairNoteFileFn CompactNoteFileFn TruncateNoteFileFn 
					    ConvertNoteFileFormatFn))

(DATATYPE NoteFile (UID Stream FullFileName HashArray (HashArraySize FIXP)
			  (NextIndexNum FIXP)
			  (Version BYTE)
			  (NextLinkNum FIXP)
			  (CheckptPtr FIXP)
			  LinkLabelsCard TableOfContentsCard ToBeFiledCard OrphansCard RegistryCard 
			  ReservedCards Menu MonitorLock ExclusiveAccessMonitor CachingProcess 
			  IndexNumsFreeList UserProps NoteFileDevice)
	  (DATATYPE NoteFileDevice
		      (ListNoteFilesFn CreateNoteFileFn DeleteNoteFileFn OpenNoteFileFn 
				       BuildHashArrayFn CloseNoteFileFn NoteFileOpenPFn 
				       CheckpointNoteFileFn NewCardUIDFn MarkCardDeletedFn 
				       PutCardPartFn GetCardPartFn ObtainWritePermissionFn 
				       ReleaseWritePermissionFn CancelCacheSubscriptionFn 
				       RepairNoteFileFn CompactNoteFileFn TruncateNoteFileFn 
				       ConvertNoteFileFormatFn))
	  (SYNONYM NoteFileDevice (Device)))
]
(/DECLAREDATATYPE (QUOTE NoteFileDevice)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER))
		  (QUOTE ((NoteFileDevice 0 POINTER)
			  (NoteFileDevice 2 POINTER)
			  (NoteFileDevice 4 POINTER)
			  (NoteFileDevice 6 POINTER)
			  (NoteFileDevice 8 POINTER)
			  (NoteFileDevice 10 POINTER)
			  (NoteFileDevice 12 POINTER)
			  (NoteFileDevice 14 POINTER)
			  (NoteFileDevice 16 POINTER)
			  (NoteFileDevice 18 POINTER)
			  (NoteFileDevice 20 POINTER)
			  (NoteFileDevice 22 POINTER)
			  (NoteFileDevice 24 POINTER)
			  (NoteFileDevice 26 POINTER)
			  (NoteFileDevice 28 POINTER)
			  (NoteFileDevice 30 POINTER)
			  (NoteFileDevice 32 POINTER)
			  (NoteFileDevice 34 POINTER)
			  (NoteFileDevice 36 POINTER)))
		  (QUOTE 38))
(/DECLAREDATATYPE (QUOTE NoteFileDevice)
		  (QUOTE (POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER))
		  (QUOTE ((NoteFileDevice 0 POINTER)
			  (NoteFileDevice 2 POINTER)
			  (NoteFileDevice 4 POINTER)
			  (NoteFileDevice 6 POINTER)
			  (NoteFileDevice 8 POINTER)
			  (NoteFileDevice 10 POINTER)
			  (NoteFileDevice 12 POINTER)
			  (NoteFileDevice 14 POINTER)
			  (NoteFileDevice 16 POINTER)
			  (NoteFileDevice 18 POINTER)
			  (NoteFileDevice 20 POINTER)
			  (NoteFileDevice 22 POINTER)
			  (NoteFileDevice 24 POINTER)
			  (NoteFileDevice 26 POINTER)
			  (NoteFileDevice 28 POINTER)
			  (NoteFileDevice 30 POINTER)
			  (NoteFileDevice 32 POINTER)
			  (NoteFileDevice 34 POINTER)
			  (NoteFileDevice 36 POINTER)))
		  (QUOTE 38))
(/DECLAREDATATYPE (QUOTE NoteFile)
		  (QUOTE (POINTER POINTER POINTER POINTER FIXP FIXP BYTE FIXP FIXP POINTER POINTER 
				  POINTER POINTER POINTER POINTER POINTER POINTER POINTER POINTER 
				  POINTER POINTER POINTER))
		  (QUOTE ((NoteFile 0 POINTER)
			  (NoteFile 2 POINTER)
			  (NoteFile 4 POINTER)
			  (NoteFile 6 POINTER)
			  (NoteFile 8 FIXP)
			  (NoteFile 10 FIXP)
			  (NoteFile 6 (BITS . 7))
			  (NoteFile 12 FIXP)
			  (NoteFile 14 FIXP)
			  (NoteFile 16 POINTER)
			  (NoteFile 18 POINTER)
			  (NoteFile 20 POINTER)
			  (NoteFile 22 POINTER)
			  (NoteFile 24 POINTER)
			  (NoteFile 26 POINTER)
			  (NoteFile 28 POINTER)
			  (NoteFile 30 POINTER)
			  (NoteFile 32 POINTER)
			  (NoteFile 34 POINTER)
			  (NoteFile 36 POINTER)
			  (NoteFile 38 POINTER)
			  (NoteFile 40 POINTER)))
		  (QUOTE 42))

(RPAQ NC.DeviceVectorsHashArray (HASHARRAY 10))
(PUTHASH (QUOTE LOCALSINGLEUSER)
	 (create NoteFileDevice OpenNoteFileFn ← (FUNCTION NCLocalDevice.OpenNoteFile)
		 CloseNoteFileFn ← (FUNCTION NCLocalDevice.CloseNoteFile)
		 BuildHashArrayFn ← (FUNCTION NCLocalDevice.BuildHashArray)
		 NoteFileOpenPFn ← (FUNCTION NCLocalDevice.NoteFileOpenP)
		 CheckpointNoteFileFn ← (FUNCTION NCLocalDevice.CheckpointNoteFile)
		 ConvertNoteFileFormatFn ← (FUNCTION NCLocalDevice.ConvertNoteFileFormat)
		 TruncateNoteFileFn ← (FUNCTION NCLocalDevice.TruncateNoteFile))
	 NC.DeviceVectorsHashArray)
(* * Stuff for local device notefiles)

(DEFINEQ

(NCLocalDevice.OpenNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 12:55")

          (* * OpenNoteFileFn for the local, single user device.)



          (* * fgh 5/22/86 First created.)


    (OR (CAR (ERSETQ (PROG ((FullName (INFILEP (fetch (NoteFile FullFileName)
							    of NoteFile)))
				    EofPtr CriticalUIDs Stream)

          (* * First check for possible errors.)


			           (if (NULL FullName)
				       then 

          (* * Error: NoteFileNotFound, Return)


					      (RETURN (QUOTE NoteFileNotFound))
				     elseif (OPENP FullName)
				       then 

          (* * Error: NoteFile already open, Return)


					      (RETURN (QUOTE NoteFileAlreadyOpen))
				     elseif (NULL (ERSETQ (SETQ Stream
								  (OPENSTREAM FullName
										(QUOTE BOTH)
										(QUOTE OLD)
										(QUOTE
										  ((TYPE BINARY)))))))
				       then 

          (* * Error: File won't open)


					      (RETURN (QUOTE NoteFileOpenFailed)))

          (* * All is okay for now, create fill in the NoteFile object a bit.)


			           (replace (NoteFile Stream) of NoteFile with Stream)
			           (replace (NoteFile FullFileName) of NoteFile with FullName)
			           (NC.SetMonitor NoteFile (CREATE.MONITORLOCK FullName))

          (* * Make sure stream is not closed by CLOSEALLs)


			           (WHENCLOSE Stream (QUOTE CLOSEALL)
						(QUOTE NO))

          (* * Get the header and check for correct version, correct checkpoint, & plausibility.)


			           (NCLocalDevice.GetNoteFileHeader NoteFile)
			           (SETQ EofPtr (GETEOFPTR (fetch (NoteFile Stream)
								  of NoteFile)))
			           (if (NOT (NCLocalDevice.NoteFileVersionOkayP NoteFile))
				       then (RETURN (NCLocalDevice.OpenFailed NoteFile
										    (QUOTE 
									  NoteFileNeedsConversion)))
				     elseif (NOT (NCLocalDevice.PlausibleNoteFileHeaderP 
											 NoteFile 
											   EofPtr))
				       then (RETURN (NCLocalDevice.OpenFailed NoteFile
										    (QUOTE 
										NoteFileHeaderBad)))
				     elseif (NCLocalDevice.NoteFileNeedsTruncationP NoteFile 
											EofPtr)
				       then (RETURN (NCLocalDevice.OpenFailed NoteFile
										    (QUOTE 
									  NoteFileNeedsTruncation))))

          (* * Go get the first six card UIDs on the file.)


			           (SETQ CriticalUIDs (NCLocalDevice.GetSpecialCardUIDs NoteFile))
			           (replace (NoteFileCriticalUIDs NoteFile) of CriticalUIDs
				      with (fetch (NoteFile UID) of NoteFile))

          (* * Return with list of special uids and NF-UID.)


			           (RETURN CriticalUIDs))))
	  (PROGN 

          (* * Open must have failed. Return a message to that effect.)


		   (NCLocalDevice.OpenFailed NoteFile)))))

(NCLocalDevice.BuildHashArray
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 12:58")

          (* * Build a hash array for a local device notefile)



          (* * fgh 5/23/86 First created.)


    (OR (CAR (ERSETQ (PROGN (replace (NoteFile HashArray) of NoteFile
				       with (NC.CreateUIDHashArray (fetch (NoteFile 
										    HashArraySize)
									  of NoteFile)))
				    (NCLocalDevice.GetHashArray NoteFile PromptWindow))))
	  (PROGN 

          (* * Build hash array failed for some reason.. This NF is definitely corrupted. Close it up and report the error.)


		   (AND (STREAMP (fetch (NoteFile Stream) of NoteFile))
			  (CLOSEF? (fetch (NoteFile Stream) of NoteFile)))
		   (replace (NoteFile Stream) of NoteFile with NIL)
		   (CLRHASH (fetch (NoteFile HashArray) of NoteFile))
		   (replace (NoteFile HashArray) of NoteFile with NIL)
		   (NC.SetMonitor NoteFile NIL)
		   (QUOTE ErrorOfUnknownOrigin)))))

(NCLocalDevice.GetNoteFileHeader
  (LAMBDA (NoteFile)                                         (* rht: "15-Nov-85 17:14")

          (* * Fill in the NoteFile object with stuff from the file.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (FullFileName (fetch (NoteFile FullFileName) of NoteFile)))
                                                             (* Recover the 30 information bytes for the notefile.)
         (SETFILEPTR Stream 0)                             (* 3 bytes for next card ID)
         (replace (NoteFile NextIndexNum) of NoteFile with (NC.ReadPtr Stream 3))
                                                             (* 3 bytes for index size)
         (replace (NoteFile HashArraySize) of NoteFile with (NC.ReadPtr Stream 3))
                                                             (* One dummy byte so that version number stays in 
							     favorite old place.)
         (NC.ReadPtr Stream 1)                               (* 1 byte for notecards version number)
         (replace (NoteFile Version) of NoteFile with (NC.ReadPtr Stream 1))
                                                             (* 3 bytes for next link ID)
         (replace (NoteFile NextLinkNum) of NoteFile with (NC.ReadPtr Stream 3))
                                                             (* 3 bytes for pointer to current checkpt ptr.)
         (replace (NoteFile CheckptPtr) of NoteFile with (NC.ReadPtr Stream 3))
                                                             (* 14 bytes for NoteFile UID.)
         (replace (NoteFile UID) of NoteFile with (NC.ReadUID NoteFile))
                                                             (* 2 bytes for future needs)
         (NC.ReadPtr Stream 2)
     NoteFile)))

(NCLocalDevice.NoteFileVersionOkayP
  (LAMBDA (NoteFile)                                         (* fgh: "23-May-86 15:46")

          (* * Is this a current version NF?)


    (EQP (fetch (NoteFile Version) of NoteFile)
	   NCLocalDevice.CurrentNoteFileVersionNumber)))

(NCLocalDevice.PlausibleNoteFileHeaderP
  (LAMBDA (NoteFile EOFPtr)                                  (* fgh: "23-May-86 15:44")

          (* * Return non-nil if notefile's header information seems reasonable.)



          (* * Changed to allow Checkpt = EOFPtr)



          (* * fgh 5/23/86 Changed to conform to Local Device NoteFile needs.)


    (LET ((NextIndexNum (fetch (NoteFile NextIndexNum) of NoteFile))
	  (HashArraySize (fetch (NoteFile HashArraySize) of NoteFile))
	  (CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (NextLinkNum (fetch (NoteFile NextLinkNum) of NoteFile))
	  (IndexWidth (CONSTANT (fetch (NoteFileVersion NoteFileIndexWidth) of (
								     NCLocalDevice.CurrentVersion)))
		      ))
         (COND
	   ((OR (LEQ NextIndexNum 0)
		  (GEQ (TIMES IndexWidth NextIndexNum)
			 EOFPtr))
	     (QUOTE BadNextIndexNum))
	   ((OR (LEQ HashArraySize 0)
		  (GEQ (TIMES IndexWidth HashArraySize)
			 EOFPtr))
	     (QUOTE BadHashArraySize))
	   ((OR (LEQ CheckptPtr 0)
		  (IGREATERP CheckptPtr EOFPtr))
	     (QUOTE BadCheckptPtr))
	   ((LESSP NextLinkNum 0)
	     (QUOTE BadNextLinkNum))
	   (T NoteFile)))))

(NCLocalDevice.CurrentVersion
  (LAMBDA NIL                                                (* fgh: "23-May-86 15:12")

          (* * Return the NoteFileVersion object corresponding to the latest release of notecards.)


    (for NoteFileVersion in NCLocalDevice.NoteFileVersionsList when (EQ (fetch
										  (NoteFileVersion
										    Version)
										   of 
										  NoteFileVersion)
										
						       NCLocalDevice.CurrentNoteFileVersionNumber)
       do (RETURN NoteFileVersion))))

(NCLocalDevice.NoteFileNeedsTruncationP
  (LAMBDA (NoteFile EofPtr)                                  (* fgh: "23-May-86 15:44")

          (* * Is the notefile bigger than its checkpoint pointer thinks?)


    (LESSP (fetch (NoteFile CheckptPtr) of NoteFile)
	     EofPtr)))

(NCLocalDevice.GetSpecialCardUIDs
  (LAMBDA (NoteFile)                                         (* fgh: "25-May-86 11:58")

          (* * Get the UIDs for the first 6 cards from NoteFile)



          (* * fgh 5/23/86 First created.)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (CriticalUIDs (create NoteFileCriticalUIDs)))

          (* * FOR Start of Index by Index Width, read the UID for the first 5 index entries. UID starts at the second byte 
	  of the index entry, hence the ADD1.)


         (for Index from 1 to 5 as FilePtr from (CONSTANT (ADD1 (fetch (
NoteFileVersion NoteFileHeaderSize) of (NCLocalDevice.CurrentVersion))))
	    by (CONSTANT (fetch (NoteFileVersion NoteFileIndexWidth) of (
								     NCLocalDevice.CurrentVersion)))
	    do (SETFILEPTR Stream FilePtr)
		 (SELECTQ Index
			    (1 (replace (NoteFileCriticalUIDs TableOfContents) of CriticalUIDs
				  with (NC.ReadUID Stream)))
			    (2 (replace (NoteFileCriticalUIDs Orphans) of CriticalUIDs
				  with (NC.ReadUID Stream)))
			    (3 (replace (NoteFileCriticalUIDs ToBeFiled) of CriticalUIDs
				  with (NC.ReadUID Stream)))
			    (4 (replace (NoteFileCriticalUIDs LinkLabels) of CriticalUIDs
				  with (NC.ReadUID Stream)))
			    (5 (replace (NoteFileCriticalUIDs Registry) of CriticalUIDs
				  with (NC.ReadUID Stream)))
			    (SHOULDN'T)))
     CriticalUIDs)))

(NCLocalDevice.OpenFailed
  (LAMBDA (NoteFile ErrorType)                               (* fgh: "23-May-86 15:40")

          (* * Open failed, clean up and return an error)



          (* * fgh 5/2/386 First created.)


    (AND (STREAMP (fetch (NoteFile Stream) of NoteFile))
	   (CLOSEF? (fetch (NoteFile Stream) of NoteFile)))
    (replace (NoteFile Stream) of NoteFile with NIL)
    (NC.SetMonitor NoteFile NIL)
    (RETURN (OR ErrorType (QUOTE NoteFileOpenFailed)))))

(NCLocalDevice.ReadIndexEntry
  (LAMBDA (NoteFile)                                         (* fgh: "25-May-86 18:36")

          (* * Get a card from current position of file and install it into notefile.)



          (* * fgh 5/23/86 First created on the basis of the old NC.ReadIndexEntry)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile)))
         (create Card
		   IndexLoc ←(GETFILEPTR Stream)
		   Status ←(NC.ReadStatus Stream)
		   UID ←(NC.ReadUID NoteFile)
		   MainLoc ←(NC.ReadPtr Stream 3)
		   LinksLoc ←(NC.ReadPtr Stream 3)
		   TitleLoc ←(NC.ReadPtr Stream 3)
		   PropListLoc ←(NC.ReadPtr Stream 3)
		   IndexDirtyFlg ← NIL
		   NoteFile ← NoteFile))))

(NCLocalDevice.GetHashArray
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 18:36")

          (* * Read the hash array off of a local device notefile, building the hash array along the way.)



          (* * fgh 5/23/86 First created on the basis of the old NC.GetHashArray.)



          (* * If PromptWindow is not a window, then its not of interest.)


    (if (NOT (WINDOWP PromptWindow))
	then (SETQ PromptWindow))

          (* * Get the hash array.)


    (if (NOT (OPENP (fetch (NoteFile Stream) of NoteFile)))
	then 

          (* * NoteFile isn't open, Error.)


	       (QUOTE NoteFileNotOpen)
      else 

          (* * Grab the monitor lock and read the index.)


	     (WITH.MONITOR (NC.FetchMonitor NoteFile)
			   (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
				 (CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
				 IndexNumsFreeList)

          (* * Set fileptr to beginning of the index.)


			        (SETFILEPTR Stream (CONSTANT (fetch (NoteFileVersion 
									       NoteFileHeaderSize)
								    of (
								     NCLocalDevice.CurrentVersion)))
					      )

          (* * Read in the index entries, creating a card for each and installing it in the hash array.)


			        (for IndexNum from 1 to CardTotal bind Card
				   eachtime (if (AND PromptWindow (EQ (IMOD IndexNum 100)
									      1))
						  then (NC.PrintMsg PromptWindow T 
									"Building hash array."
									(CHARACTER 13)
									"Processing number " IndexNum 
									" of "
									CardTotal "." (CHARACTER
									  13)))
					      (BLOCK)
				   do (SETQ Card (NCLocalDevice.ReadIndexEntry NoteFile))
					(if (EQ (fetch (Card Status) of Card)
						    (QUOTE FREE))
					    then (push IndexNumsFreeList IndexNum)
					  else (NC.InstallCardInNoteFile Card NoteFile))
				   finally (AND PromptWindow (NC.PrintMsg PromptWindow T 
									   "Building hash array."
										(CHARACTER 13)
										"Done."
										(CHARACTER 13))))

          (* * Set the free list)


			        (replace (NoteFile IndexNumsFreeList) of NoteFile with 
										IndexNumsFreeList)

          (* * Return the NoteFile NoteFile, indicating everything is okay.)


			    NoteFile)))))

(NCLocalDevice.SaveInformationPastCheckpoint
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 15:39")

          (* * Save the information on NoteFile that is past the checkpoint pointer. Assume NoteFile is closed.)



          (* * fgh 5/25/86 First created.)


    (PROG (NoteFileStream SaveStream)

          (* * Open the NoteFile)


	    (if (NULL (CAR (ERSETQ (SETQ NoteFileStream (OPENSTREAM FullFileName
										(QUOTE INPUT)
										(QUOTE OLD)
										(QUOTE
										  ((TYPE BINARY)))))))
			  )
		then (RETURN CouldNotOpenNoteFile))

          (* * Open the save file after asking the user to specify it.)


	    (if (NULL (CAR (ERSETQ (SETQ SaveStream (OPENSTREAM
					       (NC.AskUser (CONCAT (CHARACTER 13)
								       "File to save info in: ")
							     NIL NIL NIL PromptWindow T)
					       (QUOTE OUTPUT)
					       NIL
					       (QUOTE ((TYPE BINARY))))))))
		then (RETURN CouldNotOpenSaveFile))

          (* * Copy the bytes from the NoteFile to the save file.)


	    (if (NULL (ERSETQ (PROGN (NC.PrintMsg PromptWindow T "Saving extra info to " 
							    SaveFile " ...")
					     (COPYBYTES NoteFileStream SaveStream LastChkptPtr)
					     (CLOSEF SaveStream)
					     (CLOSEF NoteFileStream)
					     (NC.PrintMsg PromptWindow NIL "Done." (CHARACTER
							      13)))))
		then (CLOSEF? SaveStream)
		       (DELFILE SaveStream)
		       (CLOSEF? NoteFileStream)
		       (RETURN CopyToSaveFileFailed)
	      else (RETURN NoteFile)))))

(NCLocalDevice.TruncateNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 17:10")

          (* * Truncate a local device NoteFile back to the checkpoint pointer, offering the user the option of saving the 
	  changes in another file.)



          (* * fgh 5/25/86 First created on basis of old NC.CheckForNeededtruncation.)


    (PROG (NoteFileStream SaveStream ReturnValue)

          (* * Make sure PromptWindow is a window)


	    (OR (WINDOWP PromptWindow)
		  (SETQ PromptWindow))

          (* * Check to make NoteFile is not open. If it is, then error.)


	    (if (OPENP (fetch (NoteFile FullFileName) of NoteFile))
		then (RETURN (QUOTE NoteFileAlreadyOpen)))

          (* * First ask the user if they want to save the info past the checkpoint into a file. If there's no PromptWindow, 
	  don't bother to ask.)


	    (if (AND PromptWindow (NC.AskYesOrNo 
						"Want to save info beyond checkpoint to a file? "
						       "--" "Yes" NIL PromptWindow NIL T))
		then (if (NOT (type? NoteFile (SETQ ReturnValue (
						 NCLocalDevice.SaveInformationPastCheckpoint 
											 NoteFile 
										     PromptWindow))))
			   then                            (* Save failed for some reason.
							     Notify the user and return.)
				  (NC.PrintMsg PromptWindow T 
						 "Attempt to save information failed because "
						 ReturnValue "." (CHARACTER 13))
				  (RETURN NoteFileTruncationFailed)))

          (* * Now truncate. Confirming with the user first if there's a prompt window.)


	    (if (OR (NOT PromptWindow)
			(NC.AskYesOrNo (CONCAT (CHARACTER 13)
						   "Are you sure you want to truncate " FullFileName 
						   "? ")
					 "--" "No" NIL PromptWindow NIL T))
		then 

          (* * Notify the user if appropriate.)


		       (AND PromptWindow (NC.PrintMsg PromptWindow T "Truncating file " 
							  FullFileName " ..."))

          (* * Do the truncation.)


		       (if (CAR (ERSETQ (SETFILEINFO FullFileName (QUOTE LENGTH)
							     (fetch (NoteFile CheckptPtr)
								of NoteFile))))
			   then 

          (* * truncation succeeded.)


				  (AND PromptWindow (NC.PrintMsg PromptWindow T "Done."
								     (CHARACTER 13)))
				  (RETURN NoteFile)
			 else 

          (* * truncation failed. Notify user.)


				(AND PromptWindow (NC.PrintMsg PromptWindow NIL 
								   "Couldn't truncate "
								   FullFileName "." (CHARACTER
								     13)
								   (CHARACTER 13)))
				(RETURN (QUOTE NoteFileTruncationFailed)))
	      else 

          (* * user aborted truncation.)


		     (RETURN (QUOTE NoteFileTruncationAborted))))))

(NCLocalDevice.ConvertNoteFileFormat
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "25-May-86 17:17")

          (* * Convert a NoteFile from old version to curretn version format.)



          (* * fgh 5/25/86 First created on basis of old NC.CheckForNeededConversion.)


    (PROG ((Stream (fetch (NoteFile Stream) of NoteFile))
	     (Version (fetch (NoteFile Version) of NoteFile))
	     (FullFileName (fetch (NoteFile FullFileName) of NoteFile))
	     NewFileName)

          (* * Check if NoteFile is open. If so, its an error.)


	    (if (OPENP FullFileName)
		then (RETURN (QUOTE NoteFileAlreadyOpen)))

          (* * Is Version a sensible version number? If not, then just report an error.)


	    (if (OR (NOT (NUMBERP Version))
			(GEQ Version (CONSTANT (fetch (NoteFileVersion Version)
						      of (NCLocalDevice.CurrentVersion)))))
		then (RETURN (QUOTE BadVersionNumber)))

          (* * Is this a really old version. If so then we can't handle it.)


	    (if (LEQ Version 1)
		then (if (WINDOWP PromptWindow)
			   then (NC.PrintMsg PromptWindow T "Notefile " FullFileName 
						 " is  too old (version "
						 Version ")." (CHARACTER 13)
						 "  It must first be converted to version 2" 
						 "by opening in NoteCards release 1.2i."
						 (CHARACTER 13)
						 " Then we convert to version 3."
						 (CHARACTER 13)))
		       (RETURN (QUOTE NoteFileTooOld)))

          (* * Okay convert the NoteFile.)


	    (if (CAR (ERSETQ (SETQ NewFileName (NC.AutoloadApply* (FUNCTION 
								    NC.ConvertNoteFileVersion2To3)
									  FullFileName))))
		then 

          (* * Conversion went okay. Return the NoteFile with the new fullfilename.)


		       (replace (NoteFile FullFileName) of NoteFile with NewFileName)
		       (RETURN NoteFile)
	      else 

          (* * something went wrong during the conversion. return an error indicator.)


		     (CLOSEF? (fetch (NoteFile FullFileName) of NoteFile))
		     (RETURN (QUOTE NoteFileConversionFailed))))))
)
(DEFINEQ

(NCLocalDevice.NoteFileOpenP
  (LAMBDA (NoteFile)                                         (* fgh: "26-May-86 22:27")

          (* * Is thsi local device NoteFile Open?)



          (* * fgh 5/26/86 First created.)


    (AND (STREAMP (fetch (NoteFile Stream) of NoteFile))
	   (OPENP (fetch (NoteFile Stream) of NoteFile))
	   NoteFile)))

(NCLocalDevice.CloseNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "26-May-86 22:36")

          (* * Close the file for a local device NoteFile.)



          (* * fgh 5/26/86 First created.)


    (if (NOT (NCLocalDevice.NoteFileOpenP NoteFile))
	then (QUOTE NoteFileNotOpen)
      elseif (ERSETQ (CLOSEF (fetch (NoteFile Stream) of NoteFile)))
	then (replace (NoteFile Stream) of NoteFile with NIL)
	       NoteFile
      else (QUOTE CloseFailed))))

(NCLocalDevice.CheckpointNoteFile
  (LAMBDA (NoteFile PromptWindow)                            (* fgh: "26-May-86 23:11")

          (* * Checkpoint a local device notefile.)



          (* * fgh 5/26/86 First created.)


    (if (NOT (NCLocalDevice.NoteFileOpenP NoteFile))
	then (QUOTE NoteFileNotOpen)
      elseif (NULL (ERSETQ (PROGN (NCLocalDevice.PutHashArray NoteFile PromptWindow)
					  (replace (NoteFile CheckptPtr) of NoteFile
					     with (GETEOFPTR (fetch (NoteFile Stream)
								    of NoteFile)))
					  (NCLocalDevice.PutNoteFileHeader NoteFile))))
	then (QUOTE CheckpointFailed)
      else NoteFile)))

(NCLocalDevice.PutHashArray
  (LAMBDA (NoteFile PromptWindow AllActiveCardsFlg)          (* fgh: "26-May-86 23:31")

          (* * Write down the hash array's contents to the notefile.)



          (* * kirk 27Nov85 Added AllActiveCardsFlg for use by the compactor.)



          (* * fgh 5/26/86 Adapted from NC.PutHashArray with minor changes.)


    (LET ((CardTotal (SUB1 (fetch (NoteFile NextIndexNum) of NoteFile)))
	  (Num 0))
         (if (NOT (WINDOWP PromptWindow))
	     then (SETQ PromptWindow))
         (if PromptWindow
	     then (NC.PrintMsg PromptWindow T "Putting index array." (CHARACTER 13)
				   "Processing item number " 1 " out of " CardTotal "." (CHARACTER
				     13)))
         (NC.MapCards NoteFile
			(FUNCTION (LAMBDA (Card)
			    (if PromptWindow
				then (PROGN (SETQ Num (ADD1 Num))
						(AND (ZEROP (IREMAINDER Num 100))
						       (NC.PrintMsg PromptWindow T 
								      "Putting index array."
								      "Processing item number " Num 
								      " out of "
								      CardTotal "." (CHARACTER
									13)))))
			    (AND (if AllActiveCardsFlg
				       then (EQ (fetch (Card Status) of Card)
						    (QUOTE ACTIVE))
				     else (fetch (Card IndexDirtyFlg) of Card))
				   (NCLocalDevice.PutIndexEntry Card))))))))

(NCLocalDevice.PutIndexEntry
  (LAMBDA (Card)                                             (* fgh: "26-May-86 23:20")

          (* * Write down to the file the index entry for this card.)



          (* * fgh 5/26/86 Renamed from NC.PutIndexEntry.)


    (LET ((NoteFile (fetch (Card NoteFile) of Card)))
         (WITH.MONITOR (NC.FetchMonitor NoteFile)
		       (LET ((Stream (fetch (NoteFile Stream) of NoteFile)))
			    (SETFILEPTR Stream (fetch (Card IndexLoc) of Card))
			    (NC.WriteStatus Stream (fetch (Card Status) of Card))
			    (NC.WriteUID NoteFile (fetch (Card UID) of Card))
			    (NC.WritePtr Stream (fetch (Card MainLoc) of Card)
					 3)
			    (NC.WritePtr Stream (fetch (Card LinksLoc) of Card)
					 3)
			    (NC.WritePtr Stream (fetch (Card TitleLoc) of Card)
					 3)
			    (NC.WritePtr Stream (fetch (Card PropListLoc) of Card)
					 3)
			    (replace (Card IndexDirtyFlg) of Card with NIL))))))

(NCLocalDevice.PutNoteFileHeader
  (LAMBDA (NoteFile)                                         (* fgh: "26-May-86 23:13")

          (* * Write down to the notefile the header information extracted from the NoteFile object.)



          (* * fgh 5/26/86 Renamed from NC.PutNoteFileHeader)


    (LET ((Stream (fetch (NoteFile Stream) of NoteFile))
	  (FullFileName (fetch (NoteFile FullFileName) of NoteFile))
	  (UID (fetch (NoteFile UID) of NoteFile))
	  (NextIndexNum (fetch (NoteFile NextIndexNum) of NoteFile))
	  (HashArraySize (fetch (NoteFile HashArraySize) of NoteFile))
	  (NextLinkNum (fetch (NoteFile NextLinkNum) of NoteFile))
	  (CheckptPtr (fetch (NoteFile CheckptPtr) of NoteFile))
	  (Version (fetch (NoteFile Version) of NoteFile)))
         (WITH.MONITOR (NC.FetchMonitor NoteFile)
		       (if (OPENP Stream)
			   then                            (* Fill in the 30 information bytes for the notefile.)
				  (SETFILEPTR Stream 0)    (* 3 bytes for next card ID)
				  (NC.WritePtr Stream NextIndexNum 3) 
                                                             (* 3 bytes for index size)
				  (NC.WritePtr Stream HashArraySize 3) 
                                                             (* One dummy byte so that version number stays in 
							     favorite old place.)
				  (NC.WritePtr Stream -1 1) 
                                                             (* 1 byte for notecards version number)
				  (NC.WritePtr Stream Version 1) 
                                                             (* 3 bytes for next link ID)
				  (NC.WritePtr Stream NextLinkNum 3) 
                                                             (* 3 bytes for pointer to current checkpt ptr.)
				  (NC.WritePtr Stream CheckptPtr 3) 
                                                             (* 14 bytes for NoteFile UID.)
				  (NC.WriteUID NoteFile UID) 
                                                             (* 1 bytes for future needs)
				  (NC.WritePtr Stream -1 1)
				  NoteFile
			 else (NC.ReportError NIL "NC.PutNoteFileHeader: Stream not open!!!"))))))
)
[DECLARE: EVAL@COMPILE 

(TYPERECORD NoteFileVersion (Version NumberOfReservedCards NoteFileIndexWidth NoteFileHeaderSize))
]

(RPAQQ NC.OpenLocalNoteFilesPublicOrPrivate PRIVATE)

(RPAQQ NCLocalDevice.CurrentNoteFileVersionNumber 3)

(RPAQ NCLocalDevice.NoteFileVersionsList (LIST (create NoteFileVersion Version ← 3 
							 NumberOfReservedCards ← 20 
							 NoteFileIndexWidth ← 28 NoteFileHeaderSize ← 
							 30)))
(PUTPROPS FGHDEVICE COPYRIGHT ("Xerox Corporation" 1986))
(DECLARE: DONTCOPY
  (FILEMAP (NIL (3815 29885 (NC.AskUserAboutTruncation 3825 . 5331) (NC.OpenDatabaseFile 5333 . 5937) (
NC.OpenNoteFile 5939 . 14407) (NC.CreateNoteFile 14409 . 14696) (NC.InstallDeviceVectorInNoteFile 
14698 . 16245) (NC.InstallCriticalUIDsInNoteFile 16247 . 18601) (NC.StoreNoteFileInHashArray 18603 . 
19382) (NC.ProcessInspectAndRepairRequest 19384 . 20670) (NC.ProcessNoteFileNotFoundError 20672 . 
22713) (NC.ProcessTruncationRequest 22715 . 24374) (NC.ProcessNoteFileNeedsConversionError 24376 . 
27231) (NC.ProcessNoteFileNeedsTruncationError 27233 . 29883)) (29886 40359 (NC.CloseDatabaseFile 
29896 . 30064) (NC.CloseNoteFile 30066 . 38785) (NC.CheckpointNoteFile 38787 . 40357)) (45005 65842 (
NCLocalDevice.OpenNoteFile 45015 . 48143) (NCLocalDevice.BuildHashArray 48145 . 49248) (
NCLocalDevice.GetNoteFileHeader 49250 . 51154) (NCLocalDevice.NoteFileVersionOkayP 51156 . 51450) (
NCLocalDevice.PlausibleNoteFileHeaderP 51452 . 52738) (NCLocalDevice.CurrentVersion 52740 . 53287) (
NCLocalDevice.NoteFileNeedsTruncationP 53289 . 53587) (NCLocalDevice.GetSpecialCardUIDs 53589 . 55153)
 (NCLocalDevice.OpenFailed 55155 . 55700) (NCLocalDevice.ReadIndexEntry 55702 . 56419) (
NCLocalDevice.GetHashArray 56421 . 58949) (NCLocalDevice.SaveInformationPastCheckpoint 58951 . 60664) 
(NCLocalDevice.TruncateNoteFile 60666 . 63578) (NCLocalDevice.ConvertNoteFileFormat 63580 . 65840)) (
65843 72265 (NCLocalDevice.NoteFileOpenP 65853 . 66237) (NCLocalDevice.CloseNoteFile 66239 . 66802) (
NCLocalDevice.CheckpointNoteFile 66804 . 67525) (NCLocalDevice.PutHashArray 67527 . 68966) (
NCLocalDevice.PutIndexEntry 68968 . 70013) (NCLocalDevice.PutNoteFileHeader 70015 . 72263)))))
STOP