% adbookar.tu

unit
module  AddressBook
  export  Enter,   Delete,   Change,   LookUp, 
          PrintOut,   Load,   Save, 
          Initialize,    Finalize 

const fileName :=  "adbook.dat" 
const maxSize := 100
var size : 0 .. maxSize

type entry :
record
  name, address : string
end record

var contents : array 1 .. maxSize of entry

% Initialize address book to empty.  
procedure Initialize()
  size := 0
end Initialize

% Clear address book,
% freeing any space allocated for its elements
procedure Finalize()
  % no operation is needed for this implementation
  size := 0
end Finalize

function find (name : string) : int
  % This is a sequential search.
  var i : int := 0

  for j : 1 .. size
    if contents(j).name = name then
      i := j
      exit
    end if
  end for

  result i
end find

procedure Enter(name, address : string,
         var success : boolean)
  % Name must not be in book.
  pre find (name) = 0 

  if size < maxSize then
    size += 1
    contents(size).name := name
    contents(size).address := address
    success := true
  else
    success := false
  end if

end Enter

procedure Delete(name : string)

  const n := find (name)
  % Precondition: name must be in book.
  assert n not= 0 
  % Move last item to new empty slot.
  contents(n) := contents(size)
  size -= 1

end Delete


% Change address for this name.
% The name must already be in the book.
procedure Change(name, address : string)

  const i := find (name)
  % Precondition: name must be in book.
  assert i not= 0 
  contents(i).address := address

end Change

procedure LookUp(name : string,
           var address : string,
           var success : boolean)
  var i := find (name)

  if i > 0 then
    address := contents(i).address
    success := true
  else
    success := false
  end if

end LookUp

% Print all names and addresses in book.
procedure PrintOut()

  if size > 0 then
    for i : 1 .. size
      put contents(i).name : 10,
          contents(i).address
    end for
  else
    put "There are no entries in address book."
  end if

end PrintOut

% Read contents of book from a file.
procedure Load()
  var fileNumber : int
  open : fileNumber, fileName, get

  size := 0

  if fileNumber > 0 then % File exists?

    % Input each name and address.
    loop
      exit when eof (fileNumber)
      if size = maxSize then
        put "Sorry, address book file too big."
        put "Number of items loaded is : ", size
        exit
      end if
      size += 1
      get : fileNumber, contents(size).name : *,
        contents(size).address : *
    end loop

    close : fileNumber

  end if

end Load

% Save contents of book in a file.
procedure Save()
  var fileNumber : int
  open : fileNumber, fileName, put

  for i : 1 .. size
    put : fileNumber, contents(i).name
    put : fileNumber, contents(i).address
  end for

  close : fileNumber

end Save

end AddressBook