subroutine classic_file_init(file,version,reclen,error)
  use gbl_message
  use classic_interfaces, except_this=>classic_file_init
  use classic_types
  use classic_vars
  !---------------------------------------------------------------------
  ! @ public
  !   Initialize a new Classic file. The following elements must have
  ! been set before:
  !   file%lun
  !   file%spec
  !   file%nspec
  !---------------------------------------------------------------------
  type(classic_file_t), intent(inout) :: file     !
  integer(kind=4),      intent(in)    :: version  ! File version
  integer(kind=4),      intent(in)    :: reclen   ! Record length (words)
  logical,              intent(inout) :: error    ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='FILE'
  character(len=message_length) :: mess
  !
  if (.not.classic_initialized) then
    call classic_message(seve%e,rname,  &
      'Programming error: Classic library must be initialized first')
    error = .true.
    return
  endif
  !
  if (version.ne.1 .and. version.ne.2) then
    write(mess,'(A,I0)')  'Unsupported File Version ',version
    call classic_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  if (version.eq.1) then
    if (reclen.ne.128) then
      write(mess,'(A,I0,A)')  &
        'Version 1 file must have 128-words long records (got ',reclen,')'
      call classic_message(seve%e,rname,mess)
      error = .true.
      return
    endif
  else
    write(mess,'(A,I0,A)')  'File is version 2 (record length: ',reclen,' words)'
    call classic_message(seve%d,rname,mess)
  endif
  !
  file%desc%version = version
  file%desc%reclen = reclen
  file%readwrite = .true.
  !
  ! Fortran open the (new) file
  call classic_file_fopen(file,'NEW',error)
  if (error)  return
  !
end subroutine classic_file_init
!
subroutine classic_file_open(file,readwrite,error)
  use gbl_message
  use classic_interfaces, except_this=>classic_file_open
  use classic_types
  use classic_vars
  !---------------------------------------------------------------------
  ! @ public
  !   Open an old Classic file. The following elements must have been
  ! set before:
  !   file%lun
  !   file%spec
  !   file%nspec
  !---------------------------------------------------------------------
  type(classic_file_t), intent(inout) :: file       !
  logical,              intent(in)    :: readwrite  !
  logical,              intent(inout) :: error      ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='FILE'
  !
  if (.not.classic_initialized) then
    call classic_message(seve%e,rname,  &
      'Programming error: Classic library must be initialized first')
    error = .true.
    return
  endif
  !
  file%readwrite = readwrite
  file%desc%reclen = classic_reclen_v1  ! Default size, will be reopened if
                                        ! necessary when File Descriptor is read
  !
  ! Fortran open the (new) file
  call classic_file_fopen(file,'OLD',error)
  if (error)  return
  !
end subroutine classic_file_open
!
subroutine classic_file_close(file,error)
  use classic_types
  use classic_interfaces, except_this=>classic_file_close
  !---------------------------------------------------------------------
  ! @ public
  !  Perform the needed operations to close a classic_file_t structure
  !---------------------------------------------------------------------
  type(classic_file_t), intent(inout) :: file   !
  logical,              intent(inout) :: error  !
  !
  call deallocate_aex(file%desc,error)
  ! if (error)  continue
  !
  call classic_file_fclose(file,error)
  ! if (error)  continue
  !
end subroutine classic_file_close
!
!-----------------------------------------------------------------------
!
subroutine classic_file_fopen(file,statu,error)
  use gbl_format
  use gbl_message
  use classic_types
  use classic_interfaces, except_this=>classic_file_fopen
  !---------------------------------------------------------------------
  ! @ public
  !  Fortran-open the given Classic file. The following elements must
  ! have been set before:
  !   file%lun
  !   file%spec
  !   file%nspec
  !   file%readwrite
  !   file%desc%reclen
  !---------------------------------------------------------------------
  type(classic_file_t), intent(in)    :: file   !
  character(len=*),     intent(in)    :: statu  ! 'OLD' or 'NEW'
  logical,              intent(inout) :: error  !
  ! Local
  character(len=*), parameter :: rname='OPEN'
  integer(kind=4) :: ier
  character(len=9) :: actio
  !
  if (file%readwrite) then
    actio = 'READWRITE'
  else
    actio = 'READ'
  endif
  !
  open(unit=file%lun,                 &
       file=file%spec(1:file%nspec),  &
       access='DIRECT',               &
       form='UNFORMATTED',            &
       recl=facunf*file%desc%reclen,  &
       status=statu,                  &
       action=actio,                  &
       iostat=ier)
  !
  if (ier.ne.0) then
    error = .true.
    call classic_message(seve%e,rname,'Open error file '//file%spec)
    call classic_iostat(seve%e,rname,ier)
    return
  endif
  !
end subroutine classic_file_fopen
!
subroutine classic_file_fclose(file,error)
  use gbl_message
  use classic_types
  use classic_interfaces, except_this=>classic_file_fclose
  !---------------------------------------------------------------------
  ! @ public
  !  Fortran-close the given Classic file. The following elements must
  ! have been set before:
  !   file%lun
  !   file%spec
  !---------------------------------------------------------------------
  type(classic_file_t), intent(in)    :: file   !
  logical,              intent(inout) :: error  !
  ! Local
  character(len=*), parameter :: rname='CLOSE'
  integer(kind=4) :: ier
  !
  close(unit=file%lun,iostat=ier)
  !
  if (ier.ne.0) then
    error = .true.
    call classic_message(seve%e,rname,'Close error file '//file%spec)
    call classic_iostat(seve%e,rname,ier)
    return
  endif
  !
end subroutine classic_file_fclose
!
subroutine classic_file_fflush(file,error)
  use gbl_message
  use classic_types
  use classic_interfaces, except_this=>classic_file_fflush
  !---------------------------------------------------------------------
  ! @ public
  ! Fortran-flush the given Classic file. According to Fortran:
  !   "Execution of a FLUSH statement causes data written to an
  !    external file to be available to other processes, or causes data
  !    placed in an external file by means other than Fortran to be
  !    available to a READ statement. These actions are processor
  !    dependent."
  ! In other words, it works on both writing and reading files.
  !---------------------------------------------------------------------
  type(classic_file_t), intent(in)    :: file   !
  logical,              intent(inout) :: error  !
  ! Local
#if defined(FORTRAN2003)
  character(len=*), parameter :: rname='FLUSH'
  integer(kind=4) :: ier
  !
  flush(unit=file%lun,iostat=ier)
  !
  if (ier.ne.0) then
    error = .true.
    call classic_message(seve%e,rname,'Flush error file '//file%spec)
    call classic_iostat(seve%e,rname,ier)
    return
  endif
#else
  logical :: lerror  ! Local error flag
  !
  ! Close and reopen the file
  lerror = .false.
  call classic_file_fclose(file,lerror)
  if (lerror) then
    error = .true.
    return
  endif
  call classic_file_fopen(file,'OLD',error)
  if (lerror) then
    error = .true.
    return
  endif
#endif
  !
end subroutine classic_file_fflush
