!#########################################################################
!		
!    Copyright (C) 2003-2012 Department of Physics and Astronomy,
!                            University of Rochester,
!                            Rochester, NY
!
!    io_bov.f90 is part of AstroBEAR.
!
!    AstroBEAR is free software: you can redistribute it and/or modify	  
!    it under the terms of the GNU General Public License as published by 
!    the Free Software Foundation, either version 3 of the License, or    
!    (at your option) any later version.
!
!    AstroBEAR is distributed in the hope that it will be useful, 
!    but WITHOUT ANY WARRANTY; without even the implied warranty of
!    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!    GNU General Public License for more details.
!
!    You should have received a copy of the GNU General Public License
!    along with AstroBEAR.  If not, see <http://www.gnu.org/licenses/>.
!
!#########################################################################
!> @file io_bov.f90
!! @brief Main file for module IOBOV

!> @defgroup IOBOV IO BOV
!! @brief Writes BOV files for viewing data in visit
!! @ingroup IO

!> Writes BOV files for viewing particle data in visit
!! @ingroup IOBOV
MODULE IOBOV
   IMPLICIT NONE

CONTAINS

   SUBROUTINE WriteBOV2DScalar(name, lower, upper, tnow, data, varname)
      USE GlobalDeclarations
      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)
      USE GlobalDeclarations

      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)
      write(*,*) 'mx, my=', mx, my
      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)
      USE GlobalDeclarations
      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)
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
      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)
      USE GlobalDeclarations
      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)
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
      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)
      USE GlobalDeclarations
      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)
      WRITE(BOV_DATA_HANDLE,'(A19)')  "DATA_ENDIAN: LITTLE"
      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


