! --------------------------------------------------------
! Instituto Nacional de Pesquisas Espaciais - INPE
! Coordenacao-Geral de Ciencias da Terra - CGCT
! Divisao de Impactos, Adaptacao e Vulnerabilidade - DIIAV
!
! Projeto: SisMOM
! Sistema de Monitoramento e Modelagem Oceanica e Costeira
! --------------------------------------------------------
! Escrita dos arquivos TXT no formato Fortran (ventos e correntes).
! --------------------------------------------------------
module mod_writer
  use mod_kinds, only: sp, dp
  use mod_grid, only: grid_t
  use, intrinsic :: ieee_arithmetic, only: ieee_is_nan
  implicit none
  private
  public :: write_winds, open_currents, write_current_level, close_currents

  character(len=*), parameter :: WIND_HEADER = &
    '     i,    j,  longitude,   latitude, wind_u(10), wind_v(10),  t_air(2m)'
  character(len=*), parameter :: CURRENT_HEADER = &
    '    i,   j,   k,  longitude,   latitude, layer(m), water_u,  water_v,  '// &
    'water_w,  water_t,  water_s'

contains

  pure elemental function fnan(x, fill) result(y)
    real(sp), intent(in) :: x
    real(dp), intent(in) :: fill
    real(sp) :: y
    if (ieee_is_nan(x)) then
      y = real(fill, sp)
    else
      y = x
    end if
  end function fnan

  subroutine write_winds(path, g, u, v, t, fill)
    character(len=*), intent(in) :: path
    type(grid_t),     intent(in) :: g
    real(sp),         intent(in) :: u(:), v(:), t(:)
    real(dp),         intent(in) :: fill
    integer :: unit, i, j, p

    open(newunit=unit, file=path, status='replace', action='write')
    write(unit, '(a)') WIND_HEADER
    do j = 1, g%ny
      do i = 1, g%nx
        p = (j - 1) * g%nx + i
        write(unit, '(2i5,2f12.6,3f10.4)') i, j, g%lon(p), g%lat(p), &
             fnan(u(p), fill), fnan(v(p), fill), fnan(t(p), fill)
      end do
    end do
    close(unit)
  end subroutine write_winds

  subroutine open_currents(path, unit)
    character(len=*), intent(in)  :: path
    integer,          intent(out) :: unit
    open(newunit=unit, file=path, status='replace', action='write')
    write(unit, '(a)') CURRENT_HEADER
  end subroutine open_currents

  subroutine write_current_level(unit, g, k, layer, u, v, w, t, s, fill)
    integer,      intent(in) :: unit
    type(grid_t), intent(in) :: g
    integer,      intent(in) :: k
    real(dp),     intent(in) :: layer
    real(sp),     intent(in) :: u(:), v(:), w(:), t(:), s(:)
    real(dp),     intent(in) :: fill
    integer :: i, j, p

    do j = 1, g%ny
      do i = 1, g%nx
        p = (j - 1) * g%nx + i
        write(unit, '(3i5,2f12.6,1f8.1,5f10.4)') i, j, k, g%lon(p), g%lat(p), &
             layer, fnan(u(p), fill), fnan(v(p), fill), fnan(w(p), fill), &
             fnan(t(p), fill), fnan(s(p), fill)
      end do
    end do
  end subroutine write_current_level

  subroutine close_currents(unit)
    integer, intent(in) :: unit
    close(unit)
  end subroutine close_currents

end module mod_writer
