				% 19-JAN-2015

				% ioBinFile 522>which mmc
				% /usr/local/mercury-14.01/bin/mmc

				% ioBinFile 511>./ioBinFile 
				% Opened 'binTest' successfully.
				% Offsets rec0: 0, rec1: 32, rec2: 62.
				% ioBinFile 513>cat binTest 
				% rec("The man ran home.", 3092).
				% rec("The girl saw me.", 312).
				% rec("Each person saw you.", 532).

				% set to false, recompile main/2
				% ioBinFile 517>./ioBinFile 
				% Opened 'binTest' successfully.
				% Offset after seek: 32.
				% Read record: rec('The girl saw me.', 312)

				% Not working, just record output; first and third one removed.
				% false, false; default last term in if / then / else
				% ioBinFile 521>./ioBinFile
				% Opened 'binTest' successfully for seek writing.
				% Stream name: binTest; seek to position: 32.
				% ioBinFile 521>cat binTest
				% rec("Dr. Smith", 3).


:- module ioBinFile.		% This file name for now.
:- interface.
:- import_module io.

:- pred main(io::di, io::uo) is det.

:- implementation.
:- import_module list, float, string, maybe, char, int, math, bool.

:- type rec --->
	rec(
	    line :: string,
	    num :: int).

:- func recToStr(rec) = string is det.
recToStr(Rec) = S :-
	string.format("rec('%s', %i)", [ s(Rec^line), i(Rec^num) ], S).

				% works
:- pred initialWrite(string::in, io::di, io::uo) is det.
initialWrite(Fname, In, Out) :-
	io.open_binary_output(Fname, Result, In, Out2), % file may / may not exist

	(if Result = ok(Stream)

	then
	io.format("Opened '%s' successfully for initial writing.\n",  [s(Fname) ], Out2, Out3),
	 

	 Rec0 = rec("The man ran home.", 3092),
	 io.write_binary(Stream, Rec0, Out4, Out5),
	 io.binary_output_stream_offset(Stream, Off1, Out3, Out4),

	 Rec1 = rec("The girl saw me.", 312),
	 io.write_binary(Stream, Rec1, Out6, Out7),
	 io.binary_output_stream_offset(Stream, Off2, Out5, Out6),
	 
	 Rec2 = rec("Each person saw you.", 532),
	 io.write_binary(Stream, Rec2, Out8, Out9),
	 io.binary_output_stream_offset(Stream, Off3, Out7, Out8),
	 
	 io.format("Offsets rec0: %i, rec1: %i, rec2: %i.\n", [ i(Off1), i(Off2), i(Off3) ], Out9, Out10),
	 io.close_binary_output(Stream, Out10, Out)
	
	else if
	Result = io.error(Code)
	
	then
	io.format("Failed to open %s because of: %s\n.",
		  [ s(Fname), s(io.error_message(Code)) ], Out2, Out)
	
	else
	io.format( "Fail to unify io.error(Code).\n", [], Out2, Out)
	).

				% works
:- pred readSeek(string::in, io::di, io::uo) is det.
readSeek(Fname, In, Out) :-
	io.open_binary_input(Fname, Result, In, Out2), % file may / may not exist

	(if Result = ok(Stream)

	then
	io.format("Opened '%s' successfully for seek reading.\n",  [s(Fname) ], Out2, Out3),
	 % Offsets rec0: 0, rec1: 32, rec2: 62.
	 io.seek_binary_input(Stream, set, 32, Out3, Out4), % rec2
	 io.binary_input_stream_offset(Stream, Offset, Out4, Out5),
	 io.format("Offset after seek: %i.\n", [ i(Offset) ], Out5, Out6),	 

	 io.read_binary(Stream, ReadResult, Out6, Out7),
	 (if ReadResult = ok(Rec)
	 then
	 io.format("Read record: %s.\n", [ s(recToStr(Rec)) ], Out7, Out8),	 
	 io.close_binary_input(Stream, Out8, Out)
	 else if
	 ReadResult = io.error(RCode)
	 then
	io.format("Failed to read %s because of: %s.\n",
		  [ s(Fname), s(io.error_message(RCode)) ], Out7, Out)
	else
	 io.format( "Fail to unify io.error(RCode).\n", [], Out7, Out)
	 )
	 
	else if
	Result = io.error(Code)
	
	then
	io.format("Failed to open %s because of: %s.\n",
		  [ s(Fname), s(io.error_message(Code)) ], Out2, Out)
	
	else
	io.format( "Fail to unify io.error(Code).\n", [], Out2, Out)
	).

				% (Expecting) seek to known position in file, write record (binary).
				% Not working.
:- pred writeSeek(string::in, io::di, io::uo) is det.
writeSeek(Fname, In, Out) :-
	io.open_binary_output(Fname, Result, In, Out2), % file may / may not exist

	(if Result = ok(Stream)
				% Offsets rec0: 0, rec1: 32, rec2: 62.
	then
	io.format("Opened '%s' successfully for seek writing.\n",  [s(Fname) ], Out2, Out3),
	 io.seek_binary_output(Stream, set, 32, Out3, Out4), % rec1
	 io.binary_output_stream_offset(Stream, Offset, Out4, Out5),
	 io.binary_output_stream_name(Stream, Name, Out5, Out6),
	 io.format("Stream name: %s; seek to position: %i.\n",
		   [s(Name), i(Offset) ], Out6, Out7), % should be 32, OK
	 Rec0 = rec("Dr. Smith", 3),
	 io.write_binary(Stream, Rec0, Out7, Out8),
	 io.close_binary_output(Stream, Out8, Out)
	
	else if
	Result = io.error(Code)
	
	then
	io.format("Failed to open %s because of: %s.\n",
		  [ s(Fname), s(io.error_message(Code)) ], Out2, Out)
	
	else
	io.format( "Fail to unify io.error(Code).\n", [], Out2, Out)
	).

main(In, Out) :-
	Fname = "binTest", % Located in same directory as this program.
				% Change false to true and conversely; recompile.
				% Do initialWrite first, then readSeek to test; both working.
	(if false then
	initialWrite(Fname, In, Out)
	
	else if (false) then
	readSeek(Fname, In, Out)

	% Not working, just writes out a single record to file.
	else
	writeSeek(Fname, In, Out)
	).