!----------------------------------------------------------------------
! NetCDF (EZCDF) i/o routines -- wavecode output data (dmc Nov 2004)
!----------------------------------------------------------------------
!
!  rfxqlo_outputfile_create   --  create & write file
!                                containing output data for wavecodes
!
!  rfxqlo_outputfile_read     --  read file containing wavecode output data;
!                                reconstruct the rfxqlo_private module
!
!    rfxqlo_output_define -- define file contents
!    rfxqlo_output_write  -- write data
!    rfxqlo_output_read   -- read data, reconstruct module contents.
!
!-----------------------------------------------------
! note on reading:  xplasma file must be read first!
!    so that conversion of names to xplasma id can be done, and
!    so the data necessary for rfxqlo_private module reconstruction 
!    is available.
!
!    use xplasma eq_restore(<filename>,ierr) call.  This is a NetCDF
!    file written by a prior xplasma eq_save(<filename>,ierr) call.
!-----------------------------------------------------
subroutine rfxqlo_outputfile_create(filename,ierr)

  use ezcdf
  implicit NONE

  character*(*), intent(in) :: filename  ! Name of NetCDF file to write...
  integer, intent(out) :: ierr           ! error code, 0=normal

  integer :: icdf           ! NetCDF id

  do
     call cdf_open(icdf,trim(filename),'w',ierr)
     if(ierr.ne.0) exit

     call rfxqlo_output_define(icdf,ierr)
     if(ierr.ne.0) exit

     call rfxqlo_output_write(icdf,ierr)
     if(ierr.ne.0) exit

     exit
  enddo

  call cdf_close(icdf)

end subroutine rfxqlo_outputfile_create
!-----------------------------------------------------
subroutine rfxqlo_outputfile_read(filename,ierr)

  use ezcdf
  implicit NONE

  character*(*), intent(in) :: filename  ! Name of NetCDF file to read...
  integer, intent(out) :: ierr           ! error code, 0=normal

  integer :: icdf           ! NetCDF id

  do
     call cdf_open(icdf,trim(filename),'r',ierr)
     if(ierr.ne.0) exit

     call rfxqlo_output_read(icdf,ierr)
     if(ierr.ne.0) exit

     exit
  enddo

  call cdf_close(icdf)

end subroutine rfxqlo_outputfile_read

!================================================================
subroutine rfxqlo_output_define(icdf,ierr)

  ! define output data for RF wavecode solution

  use rfxqlo_private
  use ezcdf
  implicit NONE

  integer, intent(in) :: icdf   ! id of open NetCDF file
  integer, intent(out) :: ierr  ! status code returned (0=normal)

  !-----------------
  character*3 albl,blbl
  integer iant,inphi,i,inum,ielec,imdcv
  character*40 zname
  !-----------------

  ierr=0
  do iant=1,n_antenna
     do inphi = 1,antenna_array(iant)%num_nphi
        if(antenna_array(iant)%power*antenna_array(iant)%wnphi_vac(inphi).gt. &
             0.0d0) then
           if(.not.calculated(inphi,iant)) then
              write(lunmsg,*) ' ?rfxqlo_output_define: antenna #',iant
              write(lunmsg,*) '   Nphi=',antenna_array(iant)%nphi(inphi), &
                   ' has power; wavefield never calculated.'
              ierr=1
           endif
        endif
     enddo
  enddo
  if(ierr.ne.0) return

  call cdf_define(icdf,'n_antenna',n_antenna)
  call cdf_define(icdf,'max_nphi',max_nphi)

  call cdf_define(icdf,'run_id',rfx_sys%run_id)
  call cdf_define(icdf,'wavecode',rfx_sys%wavecode)
  call cdf_define(icdf,'time',rfx_sys%time)

  call cdf_define(icdf,'n_ions',rfx_ions%n_ions)

  inum=rfx_ions%n_ions + 2
  ielec=inum-1
  imdcv=inum

  do iant=1,n_antenna
     write(albl,'("F",i2.2)') iant
     do inphi=1,max_nphi
        write(blbl,'("N",i2.2)') inphi
        call ological('i_calc_'//blbl//'_'//albl,calculated(inphi,iant))
        if(calculated(inphi,iant)) then
           do i=1,inum
              if(i.eq.ielec) then
                 zname='nP_'//blbl//'_'//albl//'_elec'
              else if(i.eq.imdcv) then
                 zname='nP_'//blbl//'_'//albl//'_MdCv'
              else
                 zname='nP_'//blbl//'_'//albl//'_'//trim(rfx_ions%name_ions(i))
              endif

              call cdf_define(icdf,zname,outpros(inphi,iant)%xn_pwrs(i))

              zname(1:1)='X'
              call cdf_define(icdf,zname,outpros(inphi,iant)%ext_pwrs(i))
           enddo

           zname='nJ_'//blbl//'_'//albl
           call cdf_define(icdf,zname,outpros(inphi,iant)%xn_jrfe)

           zname='wf_nstate_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%nstate)

           zname='wfnorm_power_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%mode_power)

           zname='wf_coupling_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%mode_coupling)

           zname='Eplus_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%eplus)

           zname='kperp_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%skperp)

           zname='rfpol_'//blbl//'_'//albl
           call cdf_define(icdf,zname,wavefields(inphi,iant)%crfpol)

        endif
     enddo
  enddo

  contains

    subroutine ological(zname,lval)
      character*(*), intent(in) :: zname
      logical, intent(in) :: lval

      integer i

      if(lval) then
         i=1
      else
         i=0
      endif

      call cdf_define(icdf,zname,i)
    end subroutine ological

end subroutine rfxqlo_output_define

!--------------------------------------------------------------
subroutine rfxqlo_output_write(icdf,ierr)

  ! define output data for RF wavecode solution

  use rfxqlo_private
  use ezcdf
  implicit NONE

  integer, intent(in) :: icdf   ! id of open NetCDF file
  integer, intent(out) :: ierr  ! status code returned (0=normal)

  !-----------------
  character*3 albl,blbl
  integer iant,inphi,i,inum,ielec,imdcv
  character*40 zname
  !-----------------

  ierr=0
  do iant=1,n_antenna
     do inphi = 1,antenna_array(iant)%num_nphi
        if(antenna_array(iant)%power*antenna_array(iant)%wnphi_vac(inphi).gt. &
             0.0d0) then
           if(.not.calculated(inphi,iant)) then
              write(lunmsg,*) ' ?rfxqlo_output_define: antenna #',iant
              write(lunmsg,*) '   Nphi=',antenna_array(iant)%nphi(inphi), &
                   ' has power; wavefield never calculated.'
              ierr=1
           endif
        endif
     enddo
  enddo
  if(ierr.ne.0) return

  call cdf_write(icdf,'n_antenna',n_antenna,ierr); if(ierr.ne.0) return
  call cdf_write(icdf,'max_nphi',max_nphi,ierr); if(ierr.ne.0) return

  call cdf_write(icdf,'run_id',rfx_sys%run_id,ierr); if(ierr.ne.0) return
  call cdf_write(icdf,'wavecode',rfx_sys%wavecode,ierr); if(ierr.ne.0) return
  call cdf_write(icdf,'time',rfx_sys%time,ierr); if(ierr.ne.0) return

  call cdf_write(icdf,'n_ions',rfx_ions%n_ions,ierr); if(ierr.ne.0) return

  inum=rfx_ions%n_ions + 2
  ielec=inum-1
  imdcv=inum

  do iant=1,n_antenna
     write(albl,'("F",i2.2)') iant
     do inphi=1,max_nphi
        write(blbl,'("N",i2.2)') inphi
        call wlogical('i_calc_'//blbl//'_'//albl,calculated(inphi,iant),ierr)
        if(ierr.ne.0) return
        if(calculated(inphi,iant)) then
           do i=1,inum
              if(i.eq.ielec) then
                 zname='nP_'//blbl//'_'//albl//'_elec'
              else if(i.eq.imdcv) then
                 zname='nP_'//blbl//'_'//albl//'_MdCv'
              else
                 zname='nP_'//blbl//'_'//albl//'_'//trim(rfx_ions%name_ions(i))
              endif

              call cdf_write(icdf,zname,outpros(inphi,iant)%xn_pwrs(i),ierr)
              if(ierr.ne.0) return

              zname(1:1)='X'
              call cdf_write(icdf,zname,outpros(inphi,iant)%ext_pwrs(i),ierr)
              if(ierr.ne.0) return
           enddo

           zname='nJ_'//blbl//'_'//albl
           call cdf_write(icdf,zname,outpros(inphi,iant)%xn_jrfe,ierr)
           if(ierr.ne.0) return

           zname='wf_nstate_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%nstate,ierr)
           if(ierr.ne.0) return

           zname='wfnorm_power_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%mode_power,ierr)
           if(ierr.ne.0) return

           zname='wf_coupling_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%mode_coupling,ierr)
           if(ierr.ne.0) return

           zname='Eplus_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%eplus,ierr)
           if(ierr.ne.0) return

           zname='kperp_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%skperp,ierr)
           if(ierr.ne.0) return

           zname='rfpol_'//blbl//'_'//albl
           call cdf_write(icdf,zname,wavefields(inphi,iant)%crfpol,ierr)
           if(ierr.ne.0) return

        endif
     enddo
  enddo

  contains

    subroutine wlogical(zname,lval,ierr)
      character*(*), intent(in) :: zname
      logical, intent(in) :: lval
      integer, intent(out) :: ierr

      integer i

      if(lval) then
         i=1
      else
         i=0
      endif

      call cdf_write(icdf,zname,i,ierr)
    end subroutine wlogical

end subroutine rfxqlo_output_write

!--------------------------------------------------------------
subroutine rfxqlo_output_read(icdf,ierr)

  ! define output data for RF wavecode solution

  use rfxqlo_private
  use ezcdf
  implicit NONE

  integer, intent(in) :: icdf   ! id of open NetCDF file
  integer, intent(out) :: ierr  ! status code returned (0=normal)

  !-----------------
  character*3 albl,blbl
  integer iant,inphi,i,inum,ielec,imdcv,itest
  character*40 zname
  character*160 zstr
  real*8 :: ztime
  real*8, parameter :: ONE = 1.0d0
  real*8, parameter :: zsmall = 1.0d-6
  !-----------------

  if(.not.ready) then
     write(lunmsg,*) ' ?rfxqlo_output_read: not ready.'
     write(lunmsg,*) '  read input file first;'
     write(lunmsg,*) '  call rfxqlo_verify first.'
     ierr=1
     return
  else
     ierr=0
  endif

  call cdf_read(icdf,'n_antenna',itest,ierr); if(ierr.ne.0) return
  if(itest.ne.n_antenna) then
     write(lunmsg,*) ' ?rfxqlo_output_read: n_antenna from file = ',itest
     write(lunmsg,*) '  but rfxqlo module is set up with n_antenna = ', &
          n_antenna
     ierr=99; return
  endif

  call cdf_read(icdf,'max_nphi',itest,ierr); if(ierr.ne.0) return
  if(itest.ne.max_nphi) then
     write(lunmsg,*) ' ?rfxqlo_output_read: max_nphi from file = ',itest
     write(lunmsg,*) '  but rfxqlo module is set up with max_nphi = ', &
          max_nphi
     ierr=99; return
  endif

  zstr=' '
  call cdf_read(icdf,'run_id',zstr,ierr); if(ierr.ne.0) return
  if(zstr.ne.rfx_sys%run_id) then
     write(lunmsg,*) ' ?rfxqlo_output_read: run_id from file: "',trim(zstr),'"'
     write(lunmsg,*) '  but rfxqlo_module has: "',trim(rfx_sys%run_id),'".'
     ierr=99; return
  endif

  call cdf_read(icdf,'wavecode',zstr,ierr); if(ierr.ne.0) return
  if(zstr.ne.rfx_sys%wavecode) then
     write(lunmsg,*) ' %rfxqlo_output_read warning: wavecode in file: ', &
          trim(zstr)
     write(lunmsg,*) '  but wavecode recorded in module is: ', &
          rfx_sys%wavecode
  endif

  call cdf_read(icdf,'time',ztime,ierr); if(ierr.ne.0) return
  if(abs(ztime-rfx_sys%time)/max(ONE,abs(rfx_sys%time)).gt.zsmall) then
     write(lunmsg,*) ' %rfxqlo_output_read warning: time in file: ',ztime
     write(lunmsg,*) '  but time recorded in module is: ',rfx_sys%time
  endif

  call cdf_read(icdf,'n_ions',itest,ierr); if(ierr.ne.0) return
  if(itest.ne.rfx_ions%n_ions) then
     write(lunmsg,*) ' ?rfxqlo_output_read: n_ions from file = ',itest
     write(lunmsg,*) '  but rfxqlo module is set up with n_ions = ', &
          rfx_ions%n_ions
     ierr=99; return
  endif

  inum=rfx_ions%n_ions + 2
  ielec=inum-1
  imdcv=inum

  do iant=1,n_antenna
     write(albl,'("F",i2.2)') iant
     do inphi=1,max_nphi
        write(blbl,'("N",i2.2)') inphi
        call rlogical('i_calc_'//blbl//'_'//albl,calculated(inphi,iant),ierr)
        if(ierr.ne.0) return
        if(calculated(inphi,iant)) then
           do i=1,inum
              if(i.eq.ielec) then
                 zname='nP_'//blbl//'_'//albl//'_elec'
              else if(i.eq.imdcv) then
                 zname='nP_'//blbl//'_'//albl//'_MdCv'
              else
                 zname='nP_'//blbl//'_'//albl//'_'//trim(rfx_ions%name_ions(i))
              endif

              call cdf_read(icdf,zname,outpros(inphi,iant)%xn_pwrs(i),ierr)
              if(ierr.ne.0) return
              call eq_gfnum(outpros(inphi,iant)%xn_pwrs(i), &
                   outpros(inphi,iant)%id_pwrs(i))

              zname(1:1)='X'
              call cdf_read(icdf,zname,outpros(inphi,iant)%ext_pwrs(i),ierr)
              if(ierr.ne.0) return
           enddo

           zname='nJ_'//blbl//'_'//albl
           call cdf_read(icdf,zname,outpros(inphi,iant)%xn_jrfe,ierr)
           if(ierr.ne.0) return
           call eq_gfnum(outpros(inphi,iant)%xn_jrfe, &
                outpros(inphi,iant)%id_jrfe)
           if(ierr.ne.0) return

           zname='wf_nstate_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%nstate,ierr)
           if(ierr.ne.0) return

           zname='wfnorm_power_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%mode_power,ierr)
           if(ierr.ne.0) return

           zname='wf_coupling_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%mode_coupling,ierr)
           if(ierr.ne.0) return

           zname='Eplus_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%eplus,ierr)
           if(ierr.ne.0) return

           zname='kperp_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%skperp,ierr)
           if(ierr.ne.0) return

           zname='rfpol_'//blbl//'_'//albl
           call cdf_read(icdf,zname,wavefields(inphi,iant)%crfpol,ierr)
           if(ierr.ne.0) return

        endif
     enddo
  enddo

  contains

    subroutine rlogical(zname,lval,ierr)
      character*(*), intent(in) :: zname
      logical, intent(out) :: lval
      integer, intent(out) :: ierr

      integer i

      call cdf_read(icdf,zname,i,ierr)
      lval = (i.eq.1)

    end subroutine rlogical

end subroutine rfxqlo_output_read

subroutine rfxqlo_output_debug(caller)

  ! debug I/O -- DMC Apr 2009 looking for source of corruption of RF wavefield

  implicit NONE

  character*(*), intent(in) :: caller

  !-----------------------------

  integer, save ::  icount = 0
  integer :: ierr
  character*40 filename

  !-----------------------------

  icount = icount + 1

  filename = ' '
  write(filename,'("debug_output_",i4.4,".cdf")') icount

  write(6,*) ' => from '//trim(caller)//' writing rfxqlo '//trim(filename)

  call rfxqlo_outputfile_create(trim(filename),ierr)
  if(ierr.ne.0) write(6,*) ' ?rfxqlo_outputfile_create status: ',ierr

end subroutine rfxqlo_output_debug
