# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
module write_inv_params_mod
  use sep3d_struct_mod
  use tomo_space_conv_mod
  use tomo_chain_mod
  use basic_util_mod
  use sep
  implicit none
  logical,private, save :: write_rmovie_dat,write_rmovie_mod&
    &,write_rmovie_extra
  logical,private, save :: write_resid_dat,write_resid_mod&
    &,write_resid_extra
  logical,private, save :: write_xmovie,write_resid,write_rmovie
  logical, private,save :: styling_reg
  integer, private,save :: niter
  integer,private,save :: nm(3),ndat,nmod,cyclera,nm1,nm2,nm3
  real,private,save :: om(3),dm(3)
  logical, private, save :: map_dat
  contains
  logical function setup_write_files(nd,nm,ne,ni)
    integer :: nd,nm,ne,ni
    ndat=nd
    nmod=nm
    cyclera=ne
    niter=ni
    styling_reg=model_eps_diagonal()
    if (write_rmovie_dat) then
      call setup_inv_file("rmovie_dat",map_dat,.true.,ndat)
    end if
    if (write_rmovie_mod) then
      call setup_inv_file("rmovie_mod",styling_reg,.true.,nmod)
    end if
    if (write_xmovie) then
      call setup_inv_file("xmovie",.true.,.true.,nmod)
    end if
    if (write_rmovie_extra) then
      call setup_inv_file("rmovie_extra",.false.,.true.,cyclera)
    end if
    if (write_resid_dat) then
      call setup_inv_file("resid_dat",map_dat,.false.,ndat)
    end if
    if (write_resid_mod) then
      call setup_inv_file("resid_mod",styling_reg,.false.,nmod)
    end if
    if (write_resid_extra) then
      call setup_inv_file("resid_extra",.false.,.false.,cyclera)
    end if
    setup_write_files=.true.
  end function
  subroutine setup_inv_file(tag,reg,movie,nsz)
    character(len=*) :: tag
    logical :: reg,movie
    integer :: nsz,n
    if (movie) then
      n=niter
    else
      n=1
    end if
    if (reg) then
      call setup_reg_file(tag,nm,om,dm,n)
    else
      call setup_ireg_file(tag,nsz)
    end if
  end subroutine
  logical function write_out_solve_info(resid,rmovie,xmovie)
    real,pointer :: resid(:),rmovie(:,:),xmovie(:,:)
    integer :: i
    write_out_solve_info=.false.
    if (write_resid_dat) then
      call write_dat_file("resid_dat",map_dat,resid)
    end if
    if (write_resid_mod) then
      call write_mod_file("resid_mod",styling_reg,resid)
    end if
    if (write_resid_extra) then
      call write_extra_file("resid_extra",.false.,resid)
    end if
    if (write_rmovie_dat .or. write_rmovie_mod .or. write_rmovie_extra&
      &) then
      do i=1,size(rmovie,2)
        if (write_rmovie_dat) then
          call write_dat_file("rmovie_dat",map_dat,rmovie(:,i))
        end if
        if (write_rmovie_mod) then
          call write_mod_file("rmovie_mod",styling_reg,rmovie(:,i))
        end if
        if (write_rmovie_extra) then
          call write_extra_file("rmovie_extra",.false.,rmovie(:,i))
        end if
      end do
    end if
    if (write_xmovie) then
      call write_mc_file("write_xmovie",xmovie)
    end if
    write_out_solve_info=.true.
  end function
  subroutine write_mc_file(tag,vect)
    character(len=*) :: tag
    logical :: reg_it
    real :: vect(:,:)
    real :: temp(nm1*nm2*nm3)
    integer :: i,ierr
    do i=1,size(vect,2)
      ierr=model_transform_op(.false.,.false.,vect(:,i),temp)
      call srite(tag,temp,size(temp)*4)
    end do
  end subroutine
  subroutine write_extra_file(tag,reg_it,vect)
    character(len=*) :: tag
    logical :: reg_it
    real :: vect(:)
    call srite(tag,vect(ndat+nmod+1:),4*cyclera)
  end subroutine
  subroutine write_mod_file(tag,reg_it,vect)
    character(len=*) :: tag
    logical :: reg_it
    real :: vect(:)
    call srite(tag,vect(1+ndat:ndat+nmod),4*nmod)
  end subroutine
  subroutine write_dat_file(tag,reg_it,vect)
    character(len=*) :: tag
    logical :: reg_it
    real :: vect(:)
    real,pointer :: temp(:,:,:)
    if (.not. reg_it) then
      call srite(tag,vect(1:ndat),4*ndat)
    else
      call map_dat_reg(vect,temp)
      call srite(tag,temp,size(temp)*4)
      deallocate(temp)
    end if
  end subroutine
  logical function check_write_inv_pars(nit,resid,rmovie,xmovie)
    integer :: nit
    logical :: resid,rmovie,xmovie
    type(sep3d) :: vel_s
    character(len=50) :: temp
    check_write_inv_pars=.false.
    if (.not. vel_tomo_structure(vel_s)) then
      write(0,*) "trouble getting velocity structure"
      return
    end if
    call set_n_o_d_3d(vel_s,nm,om,dm)
    nm1=nm(1)
    nm2=nm(2)
    nm3=nm(3)
    call from_param("map_dat",map_dat,.false.)
    write_rmovie_dat= check_write("rmovie_dat")
    write_resid_dat= check_write("resid_dat")
    write_rmovie_mod= check_write("rmovie_mod")
    write_resid_mod= check_write("resid_mod")
    write_rmovie_extra= check_write("rmovie_extra")
    write_resid_extra= check_write("resid_extra")
    write_xmovie= check_write("xmovie")
    xmovie=write_xmovie
    if (write_rmovie_dat .or. write_rmovie_mod .or. write_rmovie_extra&
      &) then
      rmovie=.true.
    else
      rmovie=.false.
    end if
    if (write_resid_dat .or. write_resid_mod .or. write_resid_extra)&
      & then
      resid=.true.
    else
      resid=.false.
    end if
    check_write_inv_pars=.true.
  end function
end module
