# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "<stdin>"
module param_holder_mod
    implicit none
  type real_ar
    real, pointer :: val(:)
  end type
  type int_ar
    integer, pointer :: val(:)
  end type
end module
module param_check_mod
  use param_holder_mod
  use sep3d_struct_mod
  use sep
  implicit none
  character(len=128), pointer,dimension(:) :: par_int,par_real,par_int_ar&
    &,par_real_ar,par_char,par_logic
  character(len=128), pointer,dimension(:) :: c_int,c_real,c_int_ar&
    &,c_real_ar,c_char,c_logic
  real, parameter :: default_real=-999.99
  integer, parameter :: default_int=-999
  logical, pointer,dimension(:),private :: val_logic,cal_logic
  integer, pointer,dimension(:),private :: val_int,cal_int
  real, pointer,dimension(:),private :: val_real,cal_real
  character(len=128), pointer,dimension(:),private :: val_char&
    &,cal_char
  type(int_ar), pointer, dimension(:),private :: val_int_ar,cal_int_ar
  type(real_ar), pointer, dimension(:),private :: val_real_ar&
    &,cal_real_ar
  interface add_param
    module procedure add_param_int
    module procedure add_param_real
    module procedure add_param_char
    module procedure add_param_int_ar
    module procedure add_param_real_ar
    module procedure add_param_logic
  end interface
  interface check_par_file
    module procedure check_param_logic
    module procedure check_param_int
    module procedure check_param_real
    module procedure check_param_char
    module procedure check_param_int_ar
    module procedure check_param_real_ar
  end interface
  interface combo_par
    module procedure combo_par_real
    module procedure combo_par_int
  end interface
  contains
  logical function write_current(file)
    character(len=*) :: file
    integer :: i
    write_current=.false.
    if (associated(c_real)) then
      do i=1,size(c_real)
        call to_history(trim(c_real(i)),cal_real(i),file)
      end do
    end if
    if (associated(c_logic)) then
      do i=1,size(c_logic)
        call to_history(trim(c_logic(i)),cal_logic(i),file)
      end do
    end if
    if (associated(c_int)) then
      do i=1,size(c_int)
        call to_history(trim(c_int(i)),cal_int(i),file)
      end do
    end if
    if (associated(c_char)) then
      do i=1,size(c_char)
        call to_history(trim(c_char(i)),cal_char(i),file)
      end do
    end if
    if (associated(c_int_ar)) then
      do i=1,size(c_int_ar)
        call to_history(trim(c_int_ar(i)),cal_int_ar(i)%val,file)
      end do
    end if
    if (associated(c_real_ar)) then
      do i=1,size(c_real_ar)
        call to_history(trim(c_real_ar(i)),cal_real_ar(i)%val,file)
      end do
    end if
    write_current=.true.
  end function
  logical function new_par_check()
    integer :: i
    new_par_check=.false.
    if (associated(cal_int)) then
      deallocate(cal_int)
      deallocate(c_int)
    end if
    if (associated(cal_char)) then
      deallocate(cal_char)
      deallocate(c_char)
    end if
    if (associated(cal_real)) then
      deallocate(cal_real)
      deallocate(c_real)
    end if
    if (associated(cal_real_ar)) then
      do i=1,size(cal_real_ar)
        deallocate(cal_real_ar(i)%val)
      end do
      deallocate(cal_real_ar)
      deallocate(c_real_ar)
    end if
    if (associated(cal_int_ar)) then
      do i=1,size(cal_int_ar)
        deallocate(cal_int_ar(i)%val)
      end do
      deallocate(cal_int_ar)
      deallocate(c_int_ar)
    end if
    nullify(cal_int,cal_real,cal_int_ar,cal_real_ar,cal_char)
    nullify(c_int,c_real,c_int_ar,c_real_ar,c_char)
    new_par_check=.true.
  end function
  subroutine init_param_check()
    nullify(val_int,val_real,val_int_ar,val_real_ar,val_char)
    nullify(par_int,par_real,par_int_ar,par_real_ar,par_char)
    nullify(cal_int,cal_real,cal_int_ar,cal_real_ar,cal_char)
    nullify(val_logic,par_logic,cal_logic,c_logic)
    nullify(c_int,c_real,c_int_ar,c_real_ar,c_char)
  end subroutine
  subroutine add_param_real_ar(name,val)
    character(len=*) :: name
    real :: val(:)
    integer ::nc,i
    character(len=128),dimension(:),pointer :: p_save(:)
    type(real_ar),dimension(:),pointer :: val_save(:)
    if (associated(par_real_ar)) then
      call save_real_ar(par_real_ar,val_real_ar,p_save,val_save)
      nc=size(par_real_ar)
      deallocate(par_real_ar)
      call clean_real_ar(val_real_ar)
      allocate(par_real_ar(nc+1),val_real_ar(nc+1))
      do i=1,nc
        call copy_real_ar(val_save(i)%val,val_real_ar(i))
      end do
      par_real_ar(1:nc)=p_save(1:nc)
      par_real_ar(nc+1)=name
      call copy_real_ar(val,val_real_ar(nc+1))
      deallocate(p_save)
      call clean_real_ar(val_save)
    else
      allocate(par_real_ar(1),val_real_ar(1))
      par_real_ar(1)=name
      call copy_real_ar(val,val_real_ar(1))
    end if
    if (associated(c_real_ar)) then
      call save_real_ar(c_real_ar,cal_real_ar,p_save,val_save)
      nc=size(c_real_ar)
      deallocate(c_real_ar)
      call clean_real_ar(cal_real_ar)
      allocate(c_real_ar(nc+1),cal_real_ar(nc+1))
      do i=1,nc
        call copy_real_ar(val_save(i)%val,cal_real_ar(i))
      end do
      c_real_ar(1:nc)=p_save(1:nc)
      c_real_ar(nc+1)=name
      call copy_real_ar(val,cal_real_ar(nc+1))
      deallocate(p_save)
      call clean_real_ar(val_save)
    else
      allocate(c_real_ar(1),cal_real_ar(1))
      c_real_ar(1)=name
      call copy_real_ar(val,cal_real_ar(1))
    end if
  end subroutine
  subroutine save_real(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    real,pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    output=input
  end subroutine
  subroutine save_char(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    character(len=128),pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    output=input
  end subroutine
  subroutine save_logic(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    logical,pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    output=input
  end subroutine
  subroutine save_int(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    integer,pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    output=input
  end subroutine
  subroutine save_int_ar(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    type(int_ar),pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    do i=1,nc
      call copy_int_ar(input(i)%val,output(i))
    end do
  end subroutine
  subroutine save_real_ar(inpar,input,outpar,output)
    integer :: i,nc
    character(len=128),pointer, dimension(:) :: inpar,outpar
    type(real_ar),pointer,dimension(:) :: input,output
    nc=size(inpar)
    allocate(outpar(nc),output(nc))
    outpar=inpar
    do i=1,nc
      call copy_real_ar(input(i)%val,output(i))
    end do
  end subroutine
  subroutine copy_int_ar(array,struct)
    integer :: array(:)
    type(int_ar) :: struct
    allocate(struct%val(size(array)))
    struct%val=array
  end subroutine
  subroutine copy_real_ar(array,struct)
    real :: array(:)
    type(real_ar) :: struct
    allocate(struct%val(size(array)))
    struct%val=array
  end subroutine
  subroutine clean_int_ar(array)
    type(int_ar),dimension(:) :: array
    integer :: i
    do i=1,size(array)
      deallocate(array(i)%val)
    end do
  end subroutine
  subroutine clean_real_ar(array)
    type(real_ar),dimension(:) :: array
    integer :: i
    do i=1,size(array)
      deallocate(array(i)%val)
    end do
  end subroutine
  subroutine add_param_int_ar(name,val)
    character(len=*) :: name
    integer :: val(:)
    integer ::nc,i
    character(len=128),dimension(:),pointer :: p_save(:)
    type(int_ar),dimension(:),pointer :: val_save(:)
    if (associated(par_int_ar)) then
      call save_int_ar(par_int_ar,val_int_ar,p_save,val_save)
      nc=size(par_int_ar)
      deallocate(par_int_ar)
      call clean_int_ar(val_int_ar)
      allocate(par_int_ar(nc+1),val_int_ar(nc+1))
      do i=1,nc
        call copy_int_ar(val_save(i)%val,val_int_ar(i))
      end do
      par_int_ar(1:nc)=p_save(1:nc)
      par_int_ar(nc+1)=name
      call copy_int_ar(val,val_int_ar(nc+1))
      deallocate(p_save)
      call clean_int_ar(val_save)
    else
      allocate(par_int_ar(1),val_int_ar(1))
      par_int_ar(1)=name
      call copy_int_ar(val,val_int_ar(1))
    end if
    if (associated(c_int_ar)) then
      call save_int_ar(c_int_ar,cal_int_ar,p_save,val_save)
      nc=size(c_int_ar)
      deallocate(c_int_ar)
      call clean_int_ar(cal_int_ar)
      allocate(c_int_ar(nc+1),cal_int_ar(nc+1))
      do i=1,nc
        call copy_int_ar(val_save(i)%val,cal_int_ar(i))
      end do
      c_int_ar(1:nc)=p_save(1:nc)
      c_int_ar(nc+1)=name
      call copy_int_ar(val,cal_int_ar(nc+1))
      deallocate(p_save)
      call clean_int_ar(val_save)
    else
      allocate(c_int_ar(1),cal_int_ar(1))
      c_int_ar(1)=name
      call copy_int_ar(val,cal_int_ar(1))
    end if
  end subroutine
  subroutine add_param_char(name,val)
    character(len=*) :: name,val
    integer :: nc
    character(len=128),dimension(:),pointer :: p_save(:)
    character(len=128),dimension(:),pointer :: val_save(:)
    if (associated(par_char)) then
      call save_char(par_char,val_char,p_save,val_save)
      nc=size(par_char)
      deallocate(par_char,val_char)
      allocate(par_char(nc+1),val_char(nc+1))
      par_char(1:nc)=p_save
      val_char(1:nc)=val_save
      par_char(nc+1)=name
      val_char(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(par_char(1),val_char(1))
      par_char(1)=name
      val_char(1)=val
    end if
    if (associated(c_char)) then
      call save_char(c_char,cal_char,p_save,val_save)
      nc=size(c_char)
      deallocate(c_char,cal_char)
      allocate(c_char(nc+1),cal_char(nc+1))
      c_char(1:nc)=p_save
      cal_char(1:nc)=val_save
      c_char(nc+1)=name
      cal_char(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(c_char(1),cal_char(1))
      c_char(1)=name
      cal_char(1)=val
    end if
  end subroutine
  subroutine add_param_real(name,val)
    character(len=*) :: name
    real :: val
    integer :: nc
    character(len=128),dimension(:),pointer :: p_save(:)
    real,dimension(:),pointer :: val_save(:)
    if (associated(par_real)) then
      call save_real(par_real,val_real,p_save,val_save)
      nc=size(par_real)
      deallocate(par_real,val_real)
      allocate(par_real(nc+1),val_real(nc+1))
      par_real(1:nc)=p_save
      val_real(1:nc)=val_save
      par_real(nc+1)=name
      val_real(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(par_real(1),val_real(1))
      par_real(1)=name
      val_real(1)=val
    end if
    if (associated(c_real)) then
      call save_real(c_real,cal_real,p_save,val_save)
      nc=size(c_real)
      deallocate(c_real,cal_real)
      allocate(c_real(nc+1),cal_real(nc+1))
      c_real(1:nc)=p_save
      cal_real(1:nc)=val_save
      c_real(nc+1)=name
      cal_real(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(c_real(1),cal_real(1))
      c_real(1)=name
      cal_real(1)=val
    end if
  end subroutine
  subroutine add_param_logic(name,val)
    character(len=*) :: name
    logical :: val
    integer ::nc
    character(len=128),dimension(:),pointer :: p_save(:)
    logical,dimension(:),pointer :: val_save(:)
    if (associated(par_logic)) then
      call save_logic(par_logic,val_logic,p_save,val_save)
      nc=size(par_logic)
      deallocate(par_logic,val_logic)
      allocate(par_logic(nc+1),val_logic(nc+1))
      par_logic(1:nc)=p_save
      val_logic(1:nc)=val_save
      par_logic(nc+1)=name
      val_logic(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(par_logic(1),val_logic(1))
      par_logic(1)=name
      val_logic(1)=val
    end if
    if (associated(c_logic)) then
      call save_logic(c_logic,cal_logic,p_save,val_save)
      nc=size(c_logic)
      deallocate(c_logic,cal_logic)
      allocate(c_logic(nc+1),cal_logic(nc+1))
      c_logic(1:nc)=p_save
      cal_logic(1:nc)=val_save
      c_logic(nc+1)=name
      cal_logic(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(c_logic(1),cal_logic(1))
      c_logic(1)=name
      cal_logic(1)=val
    end if
  end subroutine
  subroutine add_param_int(name,val)
    character(len=*) :: name
    integer :: val
    integer ::nc
    character(len=128),dimension(:),pointer :: p_save(:)
    integer,dimension(:),pointer :: val_save(:)
    if (associated(par_int)) then
      call save_int(par_int,val_int,p_save,val_save)
      nc=size(par_int)
      deallocate(par_int,val_int)
      allocate(par_int(nc+1),val_int(nc+1))
      par_int(1:nc)=p_save
      val_int(1:nc)=val_save
      par_int(nc+1)=name
      val_int(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(par_int(1),val_int(1))
      par_int(1)=name
      val_int(1)=val
    end if
    if (associated(c_int)) then
      call save_int(c_int,cal_int,p_save,val_save)
      nc=size(c_int)
      deallocate(c_int,cal_int)
      allocate(c_int(nc+1),cal_int(nc+1))
      c_int(1:nc)=p_save
      cal_int(1:nc)=val_save
      c_int(nc+1)=name
      cal_int(nc+1)=val
      deallocate(p_save,val_save)
    else
      allocate(c_int(1),cal_int(1))
      c_int(1)=name
      cal_int(1)=val
    end if
  end subroutine
  logical function check_param_int_ar(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    integer ::fval,pval,i
    integer :: val(:),val2(100),kval
    integer, optional :: default(:)
    integer,external :: auxpar,getch
    check_param_int_ar=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      val=default_int
      call from_param(name,val)
    end if
    pval=0
    do i=1,size(val)
      if (val(i).ne.default_int) then
        pval=pval+1
      end if
    end do
    if (file(1:4).ne."NONE") then
      kval=auxpar(name,"d",val2,file)
      fval=0
      do i=1,kval
        if (val2(i).ne.default_int) then
          fval=fval+1
        end if
      end do
      if (fval.eq.pval .and. (fval.eq.0 .or. all(val2(1:fval).eq.val&
        &(1:fval)))) then
        check_param_int_ar=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_param_real_ar(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    integer ::fval,pval,i,kval
    real :: val(:),val2(100)
    real, optional :: default(:)
    integer,external :: auxpar,getch
    check_param_real_ar=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      val=default_real
      call from_param(name,val)
    end if
    pval=0
    do i=1,size(val)
      if (val(i).ne.default_real) then
        pval=pval+1
      end if
    end do
    if (file(1:4).ne."NONE") then
      kval=auxpar(name,"f",val2,file)
      fval=0
      do i=1,kval
        if (val2(i).ne.default_real) then
          fval=fval+1
        end if
      end do
      if (fval.eq.pval .and. (fval.eq.0 .or. all(val2(1:fval).eq.val&
        &(1:fval)))) then
        check_param_real_ar=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_param_char(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    integer ::fval,pval
    character(len=*) :: val
    character(len=128) ::val2
    character(len=*), optional :: default
    integer,external :: auxpar,getch
    integer :: i,nlen
    check_param_char=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      call from_param(name,val)
    end if
    if (file(1:4).ne."NONE") then
      do i=1,128
        val2(i:i)=' '
      end do
      fval=auxpar(name,"s",val2,file)
      nlen=len(trim(val))-1
      if (fval.eq.1 .and. trim(val2(1:nlen)).eq.trim(val(1:nlen)))&
        & then
        check_param_char=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_param_real(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    integer ::fval,pval
    real :: val,val2
    real, optional :: default
    integer,external :: auxpar,getch
    check_param_real=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      call from_param(name,val)
    end if
    if (file(1:4).ne."NONE") then
      fval=auxpar(name,"f",val2,file)
      if (fval.eq.1 .and. val2.eq.val) then
        check_param_real=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_param_logic(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    logical :: val,val2,fval,pval
    logical, optional :: default
    integer,external :: auxpar,getch
    check_param_logic=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      call from_param(name,val)
    end if
    if (file(1:4).ne."NONE") then
      fval=auxpar(name,"l",val2,file)
      if (fval.eq.1 .and. val2 .and. val) then
        check_param_logic=.true.
      end if
      if (fval.eq.1 .and. .not. val2 .and. .not. val) then
        check_param_logic=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_param_int(name,val,file,default)
    character(len=*) :: name,file
    character(len=160) :: out
    integer :: val,val2,fval,pval
    integer, optional :: default
    integer,external :: auxpar,getch
    check_param_int=.false.
    if (present(default)) then
      call from_param(name,val,default)
    else
      call from_param(name,val)
    end if
    if (file(1:4).ne."NONE") then
      fval=auxpar(name,"d",val2,file)
      if (fval.eq.1 .and. val2.eq.val) then
        check_param_int=.true.
      end if
    end if
    call add_param(name,val)
  end function
  logical function check_par_space(struct,tag,imin,imax,prefix)
    type(sep3d) :: struct
    integer :: n,imin,imax,i
    real :: o
    real :: d
    logical :: okay,junk
    character(len=*) :: tag,prefix
    character(len=20) :: temp_ch
    check_par_space=.false.
    if (tag(1:4).eq."NONE") then
      return
    end if
    okay=.true.
    do i=1,imin
      if (sep3d_ndims(struct) >= i) then
        if (.not. combo_par(tag,prefix,"n",i,n)) then
          okay=.false.
        end if
        if (n.ne.struct%n(i)) then
          okay=.false.
        end if
        if (.not. combo_par(tag,prefix,"o",i,o)) then
          okay=.false.
        end if
        if (abs(o-struct%o(i))>max(abs(o/100.),.0001)) then
          okay=.false.
        end if
        if (.not. combo_par(tag,prefix,"d",i,d)) then
          okay=.false.
        end if
        if (abs(d-struct%d(i))>max(.0001,abs(d/100.))) then
          okay=.false.
        end if
      else
        okay=.false.
      end if
    end do
    do i=imin+1,imax
      if (sep3d_ndims(struct) >= i) then
        if (combo_par(tag,prefix,"n",i,n)) then
          if (n.ne.struct%n(i)) then
            okay=.false.
          end if
        end if
        if ( combo_par(tag,prefix,"o",i,o)) then
          if (abs(o-struct%o(i))>max(.0001,abs(o/100.))) then
            okay=.false.
          end if
        end if
        if ( combo_par(tag,prefix,"d",i,d)) then
          if (abs(d-struct%d(i))>max(.0001,abs(d/100.))) then
            okay=.false.
          end if
        end if
      end if
    end do
    do i=1,sep3d_ndims(struct)
      write(temp_ch,"(a,a,i1)") trim(prefix),"n",i
      call add_param(temp_ch,struct%n(i))
      write(temp_ch,"(a,a,i1)") trim(prefix),"o",i
      call add_param(temp_ch,struct%o(i))
      write(temp_ch,"(a,a,i1)") trim(prefix),"d",i
      call add_param(temp_ch,struct%d(i))
    end do
    check_par_space=okay
  end function
  logical function combo_par_real(tag,p1,p2,p3,val)
    character(len=*) :: tag,p1,p2
    character(len=20) :: temp
    integer :: p3,i
    real :: val
    integer,external :: auxpar
    write(temp,"(a,a,i1)") trim(p1),trim(p2),p3
    i=auxpar(trim(temp),"f",val,trim(tag))
    if (i.eq.0) then
      combo_par_real=.false.
    else
      combo_par_real=.true.
    end if
  end function
  logical function combo_par_int(tag,p1,p2,p3,val)
    character(len=*) :: p1,p2,tag
    character(len=20) :: temp
    integer :: p3,i
    integer :: val
    integer,external :: auxpar
    write(temp,"(a,a,i1)") trim(p1),trim(p2),p3
    i=auxpar(trim(temp),"d",val,trim(tag))
    if (i.eq.0) then
      combo_par_int=.false.
    else
      combo_par_int=.true.
    end if
  end function
end module
