module xstraln_trhalo
 
  SAVE
 
  ! these globals can be increased on the fly...
 
  integer :: maxpts=1000  ! standard grid array size for structure
 
  type :: trhalo
 
     integer :: maxpts    ! max dimension of intercept and vector arrays
 
     integer :: guard     ! =12345 if track arrays are allocated.
 
     ! in cartesian coordinates [x,y,z] [m,m,m]
     REAL*8, dimension(3) :: pta,ptb   ! track start & stop points (as used)

     REAL*8 :: weight !track weight
     integer :: idbox               ! box ID
     integer :: idgen             ! generation ID
     REAL*8 :: Zspecies               ! Z of neutral associated with track
     REAL*8 :: Aspecies               ! A of neutral associated with track
     ! data on box zones crossed
 
     integer :: nzcrtk               ! number of zonesintercepted by track (0 means missed box)
     integer, dimension(:), allocatable :: nznbtk   ! box zone address
     REAL*8, dimension(:), allocatable :: xlngtk    ! segment lengths [m]
     REAL*8, dimension(:), allocatable :: pdep      ! deposition probability to end of box zone
 
  end type trhalo
 
  contains
 
    subroutine xstraln_trhalo_expand(i)
 
      type (trhalo) :: i
 
      ! increase size of arrays (implies re-initialization of structure)
 
      if(i%maxpts.ge.maxpts) then
         maxpts = 2*maxpts
      endif
 
      call xstraln_trhalo_init(i,(2*i%maxpts),.FALSE.)
 
    end subroutine xstraln_trhalo_expand
 
    subroutine xstraln_trhalo_init(i,isize,iforce)
 
      type (trhalo) :: i
      integer, intent(in) :: isize   ! desired size (or if 0 use the global)
      logical, intent(in) :: iforce
 
      ! initialize track data structure
      ! if (iforce) force the initialization; otherwise only do it if
      ! the array size variable does not match the saved global size.
      ! if i%guard indicates a prior allocation, free that memory
      ! with a dealloc call as well.
 
      ! (iforce) is a good idea on first initialization of a new object.
 
      integer jsize
 
      !-----------------------------
 
      if(iforce) then
         i%maxpts=0
         i%guard=0
 
         if(allocated(i%nznbtk)) deallocate(i%nznbtk)
         if(allocated(i%xlngtk)) deallocate(i%xlngtk)
         if(allocated(i%pdep)) deallocate(i%pdep)
 
 
      endif
 
      i%nzcrtk = 0
      i%idbox = 0
      i%idgen = 0
      i%Zspecies = 0
      i%Aspecies = 0
      i%pta = 0
      i%ptb = 0
      i%weight = 0
 
      if(isize.le.0) then
         jsize=maxpts
      else
         jsize=max(10,min(maxpts,isize))
      endif
 
      if((i%maxpts .ne. jsize)) then
 
         if(i%guard.eq.12345) call xstraln_trhalo_dealloc(i)
 
         i%maxpts = jsize
         i%guard = 12345
 
         allocate(i%nznbtk(1:jsize)); i%nznbtk = 0
         allocate(i%xlngtk(1:jsize)); i%xlngtk = 0
         allocate(i%pdep(1:jsize)); i%pdep = 0
 
      endif
    end subroutine xstraln_trhalo_init
 
    subroutine xstraln_trhalo_dealloc(i)
 
      type (trhalo) :: i
 
      ! cleanup: deallocate arrays inside track structure
 
      i%maxpts = 0
      i%guard = 0
 
      i%nzcrtk = 0
      i%idbox = 0
      i%idgen = 0
      i%Zspecies = 0
      i%Aspecies = 0
      i%pta = 0
      i%ptb = 0
      i%weight = 0
 
      deallocate(i%nznbtk)
      deallocate(i%xlngtk)
      deallocate(i%pdep)
 
    end subroutine xstraln_trhalo_dealloc
 
  end module xstraln_trhalo
