MODULE IOBOV
  USE GlobalDeclarations
  USE TreeDeclarations
  USE DataDeclarations
   IMPLICIT NONE

CONTAINS

   SUBROUTINE IOWriteBOVFrame(nframe)
      INTEGER :: nframe, j,level
      TYPE(NodeDefList), POINTER :: nodelist
      TYPE(InfoDef), POINTER :: info
      CHARACTER(LEN=18) :: Filename
      DO level=0,MaxLevel
         nodelist=>nodes(level)%p
         j=0
         DO WHILE (associated(nodelist))
            info=>nodelist%self%info
            WRITE(FileName,'(I2.2,A1,I5.5,A1,I3.3,A1,I5.5)')  level,'_', MPI_ID,'_', j,'_', nframe
            CALL WriteBOV3DVector(filename, Info%xbounds(:,1), Info%xbounds(:,2), levels(0)%tnow, Info%q(1:Info%mX(1),1:Info%mX(2),1:Info%mX(3),:), 'q')
            nodelist=>nodelist%next
            j=j+1
         END DO
      END DO
   END SUBROUTINE IOWriteBOVFrame

   SUBROUTINE WriteBOV2DScalar(name, lower, upper, tnow, data, varname)
      CHARACTER(LEN=*) :: name, varname
      CHARACTER(LEN=100) :: Filename
      REAL(KIND=qPREC) :: lower(2), upper(2), tnow
      REAL(KIND=qPREC), DIMENSION(:,:) :: data
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".dat"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=TRIM(FileName), status="replace", FORM="unformatted")
      WRITE(BOV_DATA_HANDLE) data
      CLOSE(BOV_DATA_HANDLE)
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".bov"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=Filename)
      WRITE(BOV_DATA_HANDLE,'(A6,E26.16)')  "TIME: ", tnow
      WRITE(BOV_DATA_HANDLE,'(A11,A,A4)') "DATA_FILE: ", TRIM(name), ".dat"
      WRITE(BOV_DATA_HANDLE,'(A11,3I12)')  "DATA_SIZE: ", shape(data), 1
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_FORMAT: DOUBLE"
      WRITE(BOV_DATA_HANDLE,'(A10,A)')  "VARIABLE: ", TRIM(varname)
# if defined _BIGENDIAN
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: BIG"
# else
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
#endif
      WRITE(BOV_DATA_HANDLE,'(A16)')  "CENTERING: zonal"
      WRITE(BOV_DATA_HANDLE,'(A14,3E26.16)')  "BRICK_ORIGIN: ", lower,0d0
      WRITE(BOV_DATA_HANDLE,'(A12,3E26.16)')  "BRICK_SIZE: ", upper-lower,0d0
      WRITE(BOV_DATA_HANDLE,'(A14)')  "BYTE_OFFSET: 4"
      WRITE(BOV_DATA_HANDLE,'(A17,I4)')  "DATA_COMPONENTS: ", 1
      CLOSE(BOV_DATA_HANDLE)
   END SUBROUTINE WriteBOV2DScalar


   SUBROUTINE READBOV2DScalar(FileName, lower, upper, tnow, data)
      CHARACTER(LEN=*) :: Filename
      CHARACTER(LEN=100) :: DISCARD
      REAL(KIND=qPREC) :: lower(2), upper(2), tnow, size(3), DISCARD_REAL
      REAL(KIND=qPREC), DIMENSION(:,:), POINTER :: data
      INTEGER :: mx, my, mz, nComps
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=Filename)
      READ(BOV_DATA_HANDLE,'(A6,E26.16)')  DISCARD, tnow
      READ(BOV_DATA_HANDLE,'(A11,A,A4)') DISCARD, DISCARD, DISCARD
      READ(BOV_DATA_HANDLE,'(A11,3I12)')  DISCARD, mx,my,mz
      READ(BOV_DATA_HANDLE,'(A19)')  DISCARD
      READ(BOV_DATA_HANDLE,'(A10,A)')  DISCARD, DISCARD
      READ(BOV_DATA_HANDLE,'(A19)')  DISCARD !"DATA_ENDIAN: LITTLE"
      READ(BOV_DATA_HANDLE,'(A16)')  DISCARD 
      READ(BOV_DATA_HANDLE,'(A14,3E26.16)')  DISCARD, lower,DISCARD_REAL
      READ(BOV_DATA_HANDLE,'(A12,3E26.16)')  DISCARD, size
      READ(BOV_DATA_HANDLE,'(A14)')  DISCARD !"BYTE_OFFSET: 4"
      READ(BOV_DATA_HANDLE,'(A17,I4)')  DISCARD, nComps
      CLOSE(BOV_DATA_HANDLE)
      ALLOCATE(data(mx,my))
      upper(1:2)=lower(1:2)+size(1:2)
      WRITE(FileName,'(A,A4)') Filename(1:LEN(TRIM(Filename))-4),".dat"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=TRIM(FileName), status="old", FORM="unformatted")
      READ(BOV_DATA_HANDLE) data
      CLOSE(BOV_DATA_HANDLE)

   END SUBROUTINE READBOV2DScalar




   SUBROUTINE WriteBOV2DVector(name, lower, upper, tnow, data, varname)
      CHARACTER(LEN=*) :: name, varname
      CHARACTER(LEN=100) :: Filename
      REAL(KIND=qPREC) :: lower(2), upper(2), tnow
      REAL(KIND=qPREC), DIMENSION(:,:,:) :: data
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".dat"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=TRIM(FileName), status="replace", FORM="unformatted")
      WRITE(BOV_DATA_HANDLE) reshape(data,(/size(data,3),size(data)/size(data,3)/),(/0d0/),(/2,1/))
      CLOSE(BOV_DATA_HANDLE)
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".bov"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=Filename)
      WRITE(BOV_DATA_HANDLE,'(A6,E26.16)')  "TIME: ", tnow
      WRITE(BOV_DATA_HANDLE,'(A11,A,A4)') "DATA_FILE: ", TRIM(name), ".dat"
      WRITE(BOV_DATA_HANDLE,'(A11,3I12)')  "DATA_SIZE: ", size(data,1),size(data,2),1
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_FORMAT: DOUBLE"
      WRITE(BOV_DATA_HANDLE,'(A10,A)')  "VARIABLE: ", TRIM(varname)
# if defined _BIGENDIAN
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: BIG"
# else
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
# endif
      WRITE(BOV_DATA_HANDLE,'(A16)')  "CENTERING: zonal"
      WRITE(BOV_DATA_HANDLE,'(A14,3E26.16)')  "BRICK_ORIGIN: ", lower,0d0
      WRITE(BOV_DATA_HANDLE,'(A12,3E26.16)')  "BRICK_SIZE: ", upper-lower,0d0
      WRITE(BOV_DATA_HANDLE,'(A14)')  "BYTE_OFFSET: 4"
      WRITE(BOV_DATA_HANDLE,'(A17,I4)')  "DATA_COMPONENTS: ", size(data,3)
      CLOSE(BOV_DATA_HANDLE)
   END SUBROUTINE WriteBOV2DVector


   SUBROUTINE WriteBOV3DScalar(name, lower, upper, tnow, data, varname)
      CHARACTER(LEN=*) :: name, varname
      CHARACTER(LEN=100) :: Filename
      REAL(KIND=qPREC) :: lower(3), upper(3), tnow
      REAL(KIND=qPREC), DIMENSION(:,:,:) :: data
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".dat"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=TRIM(FileName), status="replace", FORM="unformatted")
      WRITE(BOV_DATA_HANDLE) data
      CLOSE(BOV_DATA_HANDLE)
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".bov"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=Filename)
      WRITE(BOV_DATA_HANDLE,'(A6,E26.16)')  "TIME: ", tnow
      WRITE(BOV_DATA_HANDLE,'(A11,A,A4)') "DATA_FILE: ", TRIM(name), ".dat"
      WRITE(BOV_DATA_HANDLE,'(A11,3I12)')  "DATA_SIZE: ", shape(data)
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_FORMAT: DOUBLE"
      WRITE(BOV_DATA_HANDLE,'(A10,A)')  "VARIABLE: ", TRIM(varname)
# if defined _BIGENDIAN
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: BIG"
# else
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
# endif
      WRITE(BOV_DATA_HANDLE,'(A16)')  "CENTERING: zonal"
      WRITE(BOV_DATA_HANDLE,'(A14,3E26.16)')  "BRICK_ORIGIN: ", lower
      WRITE(BOV_DATA_HANDLE,'(A12,3E26.16)')  "BRICK_SIZE: ", upper-lower
      WRITE(BOV_DATA_HANDLE,'(A14)')  "BYTE_OFFSET: 4"
      WRITE(BOV_DATA_HANDLE,'(A17,I4)')  "DATA_COMPONENTS: ", 1
      CLOSE(BOV_DATA_HANDLE)
   END SUBROUTINE WriteBOV3DScalar



   SUBROUTINE WriteBOV3DVector(name, lower, upper, tnow, data, varname)
      CHARACTER(LEN=*) :: name, varname
      CHARACTER(LEN=100) :: Filename
      REAL(KIND=qPREC) :: lower(3), upper(3), tnow
      REAL(KIND=qPREC), DIMENSION(:,:,:,:) :: data
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".dat"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=TRIM(FileName), status="replace", FORM="unformatted")
      WRITE(BOV_DATA_HANDLE) reshape(data,(/size(data,4),size(data)/size(data,4)/),(/0d0/),(/2,1/))
      CLOSE(BOV_DATA_HANDLE)
      WRITE(FileName,'(A4,A,A4)') 'out/',TRIM(name),".bov"
      OPEN(UNIT=BOV_DATA_HANDLE, FILE=Filename)
      WRITE(BOV_DATA_HANDLE,'(A6,E26.16)')  "TIME: ", tnow
      WRITE(BOV_DATA_HANDLE,'(A11,A,A4)') "DATA_FILE: ", TRIM(name), ".dat"
      WRITE(BOV_DATA_HANDLE,'(A11,3I12)')  "DATA_SIZE: ", size(data,1),size(data,2),size(data,3)
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_FORMAT: DOUBLE"
      WRITE(BOV_DATA_HANDLE,'(A10,A)')  "VARIABLE: ", TRIM(varname)
# if defined _BIGENDIAN
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: BIG"
# else
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
# endif
      WRITE(BOV_DATA_HANDLE,'(A16)')  "CENTERING: zonal"
      WRITE(BOV_DATA_HANDLE,'(A14,3E26.16)')  "BRICK_ORIGIN: ", lower
      WRITE(BOV_DATA_HANDLE,'(A12,3E26.16)')  "BRICK_SIZE: ", upper-lower
      WRITE(BOV_DATA_HANDLE,'(A14)')  "BYTE_OFFSET: 4"
      WRITE(BOV_DATA_HANDLE,'(A17,I4)')  "DATA_COMPONENTS: ", size(data,4)
      CLOSE(BOV_DATA_HANDLE)
   END SUBROUTINE WriteBOV3DVector


END MODULE IOBOV


