************************************************************************
*                                                                      *
*                               FILEUTIL                               *
*                                                                      *
************************************************************************
*
* utilities for common file operations
* contains: linecount
*
************************************************************************



************************************************************************
*
* subroutine LINECOUNT
*
* determine number of lines in a file. ignores lines
* starting with the first character in ignore if
* len(ignore) is nonzero, ignore is typically "#" if set
*
* IN:  filename, ignore
* OUT: nlines = number of lines in file
*      ierr = error code
*             0: ok
*             1: file doesn't exist
*             2: error opening file
*
* FO 06/2005
************************************************************************

      subroutine linecount(nlines, filename, ignore, ierr)

      implicit none

      integer       nlines, ierr, idump, lenign
      character*(*) filename, ignore
      logical       lexist
      character*(80) buf

      lenign=len(ignore)

      idump = 50 ! see channels.inc
      nlines = 0
      inquire(file=filename, exist=lexist)
      if (lexist) then
         open(idump, file=filename, form='formatted', status='old',
     +        err=666)
 10      read(idump, '(a10)', end=20) buf
         if (lenign .ne. 0) then
            if (buf(1:1) .ne. ignore(1:1)) then
               nlines = nlines + 1
            end if
         else !ignore == ""
            nlines = nlines + 1
         end if
         goto 10
 20      close(idump)
         ierr = 0
      else
         ierr = 1 ! file doesn't exist
      endif
      return

 666  ierr = 2 ! error opening file
      return

      end ! of linecount

************************************************************************
*
* subroutine HASLINECOUNT
*
* determine if a file has a minimum number of lines
* avoids running over the complete file, ignores lines
* starting with the first character in ignore if
* len(ignore) is nonzero, ignore is typically "#" if set
*
* IN:  filename, minlines, ignore
* OUT: nlines = min(minlines, number of lines in file)
*      ierr = error code
*             0: ok
*             1: file doesn't exist
*             2: error opening file
*
* MS 09/2016
************************************************************************

      subroutine haslinecount(minlines, nlines,filename, ignore, ierr)

      implicit none

      integer        nlines, minlines, ierr, idump, lenign
      character*(*)  filename, ignore
      logical        lexist
      character*(80) buf

      idump = 50 ! see channels.inc
      nlines = 0
      lenign=len(ignore)

      inquire(file=filename, exist=lexist)
      if (lexist) then
         open(idump, file=filename, form='formatted', status='old',
     +        err=667)
 11      read(idump, *, end=21) buf
         if (lenign .ne. 0) then
            if (buf(1:1) .ne. ignore(1:1)) then
               nlines = nlines + 1
            end if
         else !ignore == ""
            nlines = nlines + 1
         end if

         if (nlines .eq. minlines) goto 21
         goto 11
 21      close(idump)
         ierr = 0
      else
         ierr = 1 ! file doesn't exist
      endif
      return

 667  ierr = 2                  ! error opening file
      return

      end ! of haslinecount

************************************************************************
*
* subroutine isASCIIFile
*
* guess if a file is ASCII by reading the first 32 bytes
* IN:  filename
* OUT: isascii = .true. if ascii, .false. otherwise
*      ierr = error code
*             0: ok
*             1: file doesn't exist
*             2: error opening file
*             3: error reading file
*
* MS 07/2016
************************************************************************

      subroutine isASCIIFile(filename, isascii, ierr)
      implicit none
      character*(*) filename
      logical isascii, lexist
      integer ierr
      character*(32) buf
      integer        idump, acount, lfcount, n,n1

      idump = 50                ! see channels.inc
      ierr = 0

      inquire(file=filename, exist=lexist)
      if (.not. lexist) then
         ierr = 1
         return
      end if

      inquire(file=filename,formatted=buf)

      if (buf(1:3) .eq. 'YES') then
         isascii = .true.
      elseif (buf(1:2) .eq. 'NO') then
         isascii = .false.
      else  !unknown

         ! we check the first 32 bytes if they are ascii

         ! older compilers may have a problem with "access=stream"
         open(idump,file=filename, access='stream', action="read",
     +        err=777)

         read(idump,err=778) buf
         close(idump)

         acount = 0
         lfcount = 0
         do n=1,32

            n1 = ichar(buf(n:n))

            ! ascii: line feeds and cartrige return: 10, 13
            if (n1 .eq. 10 .or. n1 .eq. 13) then
               lfcount = lfcount + 1
            end if
            ! regular ascii characters: 32 - 126
            if ( n1 .ge. 32 .and. n1 .le. 126 ) then
               acount = acount +1
            end if
         end do
         if (acount + lfcount .eq. 32) then
            isascii = .true.
         else
            isascii = .false.
         end if

      end if

      return

 777  ierr = 2 ! error opening file
      return

 778  ierr = 3 ! error reading file
      return

      end
