COMPILE SUBROUTINE Audit_MFS(Code, BFS, Handle, Name, FMC, Record, Status)

DECLARE Subroutine Msg, FSMsg

COMMON /FILENAME/ Files_Array, Handles_Array

$INSERT FILE.SYSTEM.ONGOSUB
$INSERT FILE.SYSTEM.EQUATES
$INSERT MSG_EQUATES
$INSERT AUDIT_EQUATES
$INSERT DICT_EQUATES

EQU ReadRec$ TO 1

EQU Master$		TO 1
EQU Dependent$	TO 2
	
	
RETURN

/* Directly called functions - don't pass to next file system */

INSTALL:
FLUSH:
UNLOCK.ALL:
FLUSH.CACHE:

Status = 1
RETURN

/* Not available to MFS */
	
LOCK.SEMAPHORE:
UNLOCK.SEMAPHORE:
SET.USER.SEMAPHORE:

RETURN

/* Directory level calls */

CREATE.MEDIA:
OPEN.MEDIA:
CLOSE.MEDIA:
READ.MEDIA:
WRITE.MEDIA:
GROUP.NUMBER:
RECORD.COUNT:
CREATE.FILE:
RENAME.FILE:
MOVE.FILE:
DELETE.FILE:

Goto NEXT.FS

OPEN.FILE:
	
	* Call BFS in order to get file handle
	
	FS = DELETE(BFS,1,1,1)
	NEXTFS = FS<1,1,1>
	CALL @NEXTFS(Code, FS, Handle, Name, FMC, Record, Status)
	
	* Load handle and file name into labelled common
	
	IF Status THEN
		LOCATE Name IN Files_Array USING @FM SETTING POS THEN
			Handles_Array<POS> = Record
		END ELSE
			Files_Array<-1> = Name
			Handles_Array<-1> = Record
		END
	END
	RETURN

CLEARFILE:
REMAKE.FILE:
SELECT:
READNEXT:
CLEARSELECT:

READ.RECORD:
READO.RECORD:
	
	GOTO NEXT.FS
	
WRITE.RECORD:

	* Get original record and compare with RECORD being written
	
	LOCATE Handle IN Handles_Array USING @FM SETTING POS ELSE
		mesg = "Missing file handle in AUDIT_MFS!|"
		mesg := handle
		MSG('',mesg)
		Status = 0
		RETURN
	END
			
	OPEN 'AUDIT' TO Audit_File ELSE
		MSG('',"Put FSMSG in AUDIT_MFS")
		*FSMsg()
		Status = 0
		RETURN
	END

	Write_Flag	= 0
	Org_Rec		= ''
	NextFS 		= BFS<1,1,2>
	
	CALL @NextFS(ReadRec$, FS, Handle, Name, FMC, Org_Rec, Status)  ;* Read old record
	
	File_Name = Files_Array<POS>[1,'*']		;* Extract corresponding file name
	
	Time_Date = TimeDate()
	Date_Time = FIELD(Time_Date,' ',2,4):" ":Time_Date[1,' ']
	DTM = ICONV(Date_Time,'DT2/^S')
	
	Audit_Key = File_Name:"*":@USERNAME:"*":DTM:"*":Name
	
	IF Status THEN
	
		* Original record found - check for changes
		
		IF RECORD NE Org_Rec THEN
			
			Write_Flag = 1
			
			AMV_Master 		= 0		;* Flag for Master value found
			AMV_Dependent 	= 0		;* Flag for Dependent value found
			AMV_List 		= ''	;* Master & Dependent field numbers

			* Record has been modified - write changes to history

			Pct_Field = XLATE('DICT.':File_Name,'%FIELDS%','',"X")

			Audit_Rec = 'Change'	;* Initialize audit record & load field 1
			Change_Cnt = 1

			FOR I = 1 TO Pct_Field<FIELDS_MAXFIELD$>
				IF RECORD<I> NE Org_Rec<I> THEN
				
					IF I = AMV_List<Master$> THEN AMV_Master = 1
					LOCATE I IN AMV_List<Dependent$> USING @VM SETTING DUMMY THEN AMV_Dependent = 1
					
					LOCATE I IN Pct_Field<FIELDS_FIELD_NO$> USING @VM SETTING POS THEN
					
						Field_Name	= Pct_Field<FIELDS_NAME$,POS>
						New_Val		= RECORD<I>
						Old_Val		= Org_Rec<I>
						
						CONVERT @VM TO '}' IN New_Val		
						CONVERT @VM TO '}' IN Old_Val	
						
						Audit_Rec<AUDIT_FIELDS$,Change_Cnt> = Field_Name
						Audit_Rec<AUDIT_NEW_VALS$,Change_Cnt> = New_Val
						Audit_Rec<AUDIT_OLD_VALS$,Change_Cnt> = Old_Val
						Change_Cnt += 1
						 
					END ; * End of check for field number in Pct_Fields

				END ; * End of check for matching field
					
			NEXT I
			
			IF AMV_Dependent AND NOT(AMV_Master) THEN
				
				* Dependent fields updated - write the master field also
				
				Master_Field = AMV_List<Master$>
				
				LOCATE Master_Field IN Pct_Field<FIELDS_FIELD_NO$> USING @VM SETTING POS THEN
			
					Field_Name	= Pct_Field<FIELDS_NAME$,POS>
					New_Val		= RECORD<Master_Field>
					Old_Val		= Org_Rec<Master_Field>
					
					CONVERT @VM TO '}' IN New_Val		
					CONVERT @VM TO '}' IN Old_Val	
					
					Audit_Rec<AUDIT_FIELDS$,Change_Cnt> = Field_Name
					Audit_Rec<AUDIT_NEW_VALS$,Change_Cnt> = New_Val
					Audit_Rec<AUDIT_OLD_VALS$,Change_Cnt> = Old_Val
					Change_Cnt += 1
						
				END ; * End of locate
					
			END ;* End of check for master multivalue flag

		END ; * End of global record check

	END ELSE
		* Old record not found => This is a new record being written
		
		Audit_Rec	= 'Created'
		Write_Flag	= 1
	
	END ; * End of Status check
	
	IF Write_Flag THEN
		WRITE Audit_Rec ON Audit_File,Audit_Key ELSE
			MSG('',"Put FSMSG in AUDIT_MFS")
			*FSMsg()
			Status = 0
			RETURN
		END
	END
	
	GOTO NEXT.FS


DELETE.RECORD:

LOCATE Handle IN Handles_Array USING @FM SETTING POS ELSE
	mesg = "Missing file handle in AUDIT_MFS!|"
	mesg := handle
	MSG('',mesg)
	Status = 0
	RETURN
END
		
OPEN 'AUDIT' TO Audit_File ELSE
	MSG('',"Put FSMSG in AUDIT_MFS")
	*FSMsg()
	Status = 0
	RETURN
END

Org_Rec	= ''
NextFS 	= BFS<1,1,2>

CALL @NextFS(ReadRec$, FS, Handle, Name, FMC, Org_Rec, Status)  ;* Read old record

File_Name = Files_Array<POS>[1,'*']		;* Extract corresponding file name

Time_Date = TimeDate()
Date_Time = FIELD(Time_Date,' ',2,4):" ":Time_Date[1,' ']
DTM = ICONV(Date_Time,'DT2/^S')

Audit_Key = File_Name:"*":@USERNAME:"*":DTM:"*":Name

Audit_Rec = 'Deleted'
Audit_Rec<AUDIT_DEL_RECORD$> = Org_Rec ; * Put the old record in Audit_Rec<5>

WRITE Audit_Rec ON Audit_File,Audit_Key ELSE
	MSG('',"Put FSMSG in AUDIT_MFS")
	*FSMsg()
	Status = 0
	RETURN
END

GOTO NEXT.FS

/*   Unused calls  */
LOCK.RECORD:
UNLOCK.RECORD:
RESERVED:
OMNI.SCRIPT:

CREATE.INDEX:
DELETE.INDEX:
SELECT.INDEX:
UPDATE.INDEX:
READNEXT.INDEX:

NEXT.FS:

	FS = DELETE(BFS,1,1,1)
	NEXTFS = FS<1,1,1>
	CALL @NEXTFS(Code, FS, Handle, Name, FMC, Record, Status)
	RETURN
