MODULE NFFIO
!
!   NAME:       NFCUI                                      
!   STATUS:     Ver. 1.0                                              
!   PURPOSE:    File I/O utilities              
!   LIBRARY:    MATH                                                  
!   TYPE:       SINGLE, DOUBLE PRECISION                              
!   AUTHOR:     Shigeru Inagaki                                       
!               National Institute for Fusion Science                 
!               +81-572-58-2143                                       
!               inagaki@LHD.nifs.ac.jp                                
!                                                                     
!   DESCRIPTION:                                                      
!     File I/O utilities, such as FINDFILE, are included.  
!                                                                     
!   SEE ALSO: nfport.f90 portability.c              
!   CALLED:                                                            
!   REVISION HISTORY:                                                 
!     01-JUL-2004 (CREATION)                                          
!   COMMENTS:                                                         
!              
  USE NFNUM_KINDS, ONLY : i4b, lgt
!
  IMPLICIT NONE
!
  PRIVATE
!
  INTEGER(i4b),     PARAMETER :: MAXLEN = 512
  CHARACTER(LEN=6), PARAMETER :: FMT = "(A512)"
  CHARACTER(LEN=1) :: dir_separator = '/'
!
  PUBLIC :: SET_WINDOWS_PATHNAME
  PUBLIC :: FINDFILE, REMOVEFILE, NEWUNIT
  PUBLIC :: PATHCHECK
  PUBLIC :: SKIPLINE, FINDMARK
!
CONTAINS
!
!-------------------------------------------------------
!
SUBROUTINE SET_WINDOWS_PATHNAME
  dir_separator = '\'
  RETURN
END SUBROUTINE SET_WINDOWS_PATHNAME
!
!-------------------------------------------------------
!
FUNCTION FINDFILE(fn)
!
! Return true if file = fn exists.
!
  CHARACTER(LEN=*), INTENT(IN) :: fn
  LOGICAL(lgt) :: FINDFILE
!
  LOGICAL(lgt) :: stat
!
  INQUIRE(FILE=TRIM(fn), EXIST=stat)
  FINDFILE = stat
  RETURN
END FUNCTION FINDFILE
!
!-------------------------------------------------------
!
FUNCTION NEWUNIT() RESULT(u)
!
! Find an unused file handle (or 'channel') that can be
! used for file I/O.
!
  INTEGER(i4b) :: u
!
  LOGICAL(lgt) :: stat
!
  u = 10
  DO
    INQUIRE(u, OPENED = stat)
    IF (.NOT. stat) THEN
       EXIT
    ELSE
       u = u + 1
    ENDIF
  ENDDO
  RETURN
END FUNCTION NEWUNIT
!
!-------------------------------------------------------
!
FUNCTION REMOVEFILE(fn) RESULT(istat)
  CHARACTER(LEN=*), INTENT(in) :: fn
  INTEGER(i4b) :: istat
!
  INTEGER(i4b) :: u
  LOGICAL(lgt) :: stat
!
  INQUIRE(FILE=fn, EXIST=stat)
  IF (stat) THEN
!   Delete file
    u = NEWUNIT()
    OPEN(UNIT=u, FILE=fn, IOSTAT=istat, STATUS='OLD')
    CLOSE(UNIT=u, STATUS='DELETE', IOSTAT=istat)
  ELSE
!   File does not exist.
    istat = -1
  ENDIF
  RETURN
END FUNCTION REMOVEFILE
!
!-------------------------------------------------------
!
SUBROUTINE PATHCHECK(path)
!
! Check path. If not terminated by / or \, add it.             
!
  CHARACTER(LEN=*), INTENT(INOUT) :: path
!
  INTEGER(i4b) :: ilen
!
  ilen = LEN_TRIM(path)
  IF (ilen < 1) THEN
    RETURN
  ENDIF
  IF (path(ilen:ilen) /= dir_separator) THEN
    path = TRIM(path)//dir_separator
  ENDIF
  RETURN
END SUBROUTINE PATHCHECK
!
!-------------------------------------------------------
!
FUNCTION SKIPLINE(u, nskip)
  INTEGER(i4b), INTENT(IN) :: u
  INTEGER(i4b), INTENT(IN) :: nskip
  LOGICAL(lgt) :: SKIPLINE
!
  INTEGER(i4b) :: i, istat
  CHARACTER(LEN=MAXLEN) :: line
!
  SKIPLINE = .TRUE.
  DO i = 1, nskip
    READ(u, FMT, IOSTAT = istat) line  
    IF (istat > 0) THEN
      SKIPLINE = .FALSE.
      EXIT
    ENDIF
  ENDDO
  RETURN   
END FUNCTION SKIPLINE
!
!-------------------------------------------------------
!
FUNCTION FINDMARK(u, mark, case_insensitive)
  USE NFSTR, ONLY : TOLOWER
!
  INTEGER(i4b),     INTENT(IN) :: u
  CHARACTER(LEN=*), INTENT(IN) :: mark
  LOGICAL(lgt), OPTIONAL, INTENT(IN) :: case_insensitive
  LOGICAL(lgt) :: FINDMARK
!
  INTEGER(i4b) :: istat, ilen
  CHARACTER(LEN=MAXLEN) :: line
  CHARACTER(LEN=LEN_TRIM(mark)) :: tmp
  LOGICAL(lgt) :: case_sensitive
!
  case_sensitive = .TRUE.
  ilen  = LEN_TRIM(mark)
  IF (PRESENT(case_insensitive)) THEN
    case_sensitive = (.NOT. case_insensitive)
  ENDIF 
  IF (case_sensitive) THEN
    tmp = TRIM(mark)
  ELSE
    tmp = TOLOWER(mark)
  ENDIF
!
  DO
    READ(u, FMT, IOSTAT = istat) line
    IF (istat > 0) THEN
      FINDMARK = .FALSE.
      EXIT
    ENDIF
    line = ADJUSTL(line)
    IF (.NOT. case_sensitive) THEN
      line = TOLOWER(line)
    ENDIF
    IF (line(1:ilen) == tmp(1:ilen)) THEN
      FINDMARK = .TRUE.
      EXIT
    ENDIF
  ENDDO
  RETURN
END FUNCTION FINDMARK
!
END MODULE NFFIO
