
 module branch_plot_results_mod
 
 
    implicit none
    
!---spoof some dummy constants for this test program    
    real(8)      , parameter :: r4undef  = -1d31
    character(10), parameter :: cunused  = '...unused'
    integer      , parameter :: lenheadj = 128
    integer      , parameter :: pcnone   = 128
    integer      , parameter :: i4undef = -7777
    
    type, public :: system_variable_type
       sequence
       real(8)                           :: val    = r4undef ! the value itself (that is, the content of dataj(index))
       integer                           :: index  = -1
       character(len=lenheadj)           :: header = CUNUSED ! the header for this sytem variable (i.e., the content of headj(index))
       integer                           :: utype  = pcnone  ! the unit type for this system variable (i.e. the content of utypej(index))
    end type system_variable_type

    type branch_plot_results_ppv_type   ! "Pointer to Plot vector" type
      sequence
      real(8)       , allocatable  :: v(:)      ! this array will be allocated in routine plotc_allocate_appv (in psim\plotc.f90).
                                                ! it will be sized to hold the entire contents of the array DATAC (in common, see plotc.i).
                                                ! thus each element will hold one result from the segment. The array APPV (see below) will
                                                ! hold pointers to lots of these.
      integer                     :: handle = 0 ! handle of fluid flowing at this position
      character(256), allocatable :: label      ! label of node or equipment at this position
    end type branch_plot_results_ppv_type
    
    type branch_plot_results_type
      sequence
      
      type(branch_plot_results_ppv_type), allocatable :: appv(:)                        ! array of pointers to profile plot vectors for this branch/case
      integer                                         :: end_appv             = 0       ! points to the last used element of ppa
      integer                                         :: iu_appv              = 0       ! value of IUOUT used to populate the plot vectors
      integer                                         :: item_ordinal_in_appv = i4undef ! the element number of each appv array that holds the equipment number
      type(system_variable_type        ), allocatable :: system_variables(:)            ! deconvoluted system plot variables (copy of the global dataj) for this branch/case cboneti 2012/DEC/13  
   
    end type branch_plot_results_type

    CONTAINS
    
    !---------------------------------------------------------------------
    
      subroutine construct_branch_plot_results(res)
        type (branch_plot_results_type), allocatable, intent(inout) :: res
        if(.not.allocated(res)) allocate(res)
      end subroutine 
        
    !---------------------------------------------------------------------
      
      subroutine destroy_branch_plot_results(res)
        type (branch_plot_results_type), allocatable, intent(inout) :: res
        if(allocated(res)) then
          call destroy_branch_plot_results_appv(res%appv)
          if(allocated(res%system_variables)) deallocate(res%system_variables)
          deallocate(res)
        endif
      end subroutine 
        
    !---------------------------------------------------------------------
      
      subroutine copy_branch_plot_results(from,to)
        type (branch_plot_results_type), allocatable, intent(in   ) :: from
        type (branch_plot_results_type), allocatable, intent(inout) :: to
        
        if(allocated(from)) then
          call construct_branch_plot_results(to)
          to = from
        else
          call destroy_branch_plot_results(to)
        endif
          
      end subroutine 
      
    !---------------------------------------------------------------------

      subroutine construct_branch_plot_results_appv(appv,asize)
      
        type(branch_plot_results_ppv_type), allocatable, intent(inout) :: appv(:) 
        integer,                               optional, intent(in   ) :: asize
        
        integer ii, isize
        
        if(allocated(appv)) then
          if(present(asize)) then
            if(asize.ne.size(appv)) then
              deallocate(appv)
            endif
          endif
        endif
        
        if(.not.allocated(appv)) then
          isize = 1
          if(present(asize)) isize = asize
          allocate(appv(isize)) 
        endif
        
      end subroutine construct_branch_plot_results_appv
      
!---------------------------------------------------------------------
        
      
      
      subroutine destroy_branch_plot_results_appv(appv)
        type(branch_plot_results_ppv_type), allocatable, intent(inout) :: appv(:) 
        integer ii
        if(allocated(appv)) then
          do ii = 1, size(appv)
            if(allocated(appv(ii)%v    )) deallocate(appv(ii)%v    )
            if(allocated(appv(ii)%label)) deallocate(appv(ii)%label)
          enddo
          deallocate(appv)
        endif
      end subroutine destroy_branch_plot_results_appv

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


      
      subroutine copy_branch_plot_results_appv(from, to)
      
        type(branch_plot_results_ppv_type), allocatable, intent(in   ) :: from(:)
        type(branch_plot_results_ppv_type), allocatable, intent(inout) :: to  (:)
        
        call destroy_branch_plot_results_appv(to)
        
        if(allocated(from)) then
          allocate(to(size(from)))
          to = from
        endif
        
      end subroutine copy_branch_plot_results_appv

!---------------------------------------------------------------------
      
      subroutine grow_branch_plot_results_appv(appv,asize)
    
        type(branch_plot_results_ppv_type), allocatable, intent(inout) :: appv(:) 
        integer,                               optional, intent(in   ) :: asize
    
        integer ii, nsize, osize
        
        type(branch_plot_results_ppv_type), allocatable :: new_appv(:) 
    
        if(.not.allocated(appv)) then
          call construct_branch_plot_results_appv(appv,asize)
        else
          osize = size(appv)
          if(present(asize)) then
            nsize = asize
          else
            nsize = osize*2
          endif
          if(nsize.ne.size(appv)) then
            call construct_branch_plot_results_appv(new_appv,nsize)
            do ii = 1, min(osize, nsize)
              call move_alloc(appv(ii)%v    , new_appv(ii)%v)
                          new_appv(ii)%handle =   appv(ii)%handle
              !!call move_alloc(appv(ii)%label, new_appv(ii)%label) ... causes catastrophic compiler error, try this:
              if(allocated(appv(ii)%label)) then
                allocate(new_appv(ii)%label)
                new_appv(ii)%label = appv(ii)%label
              endif
            enddo
            call destroy_branch_plot_results_appv(appv)
            call move_alloc(new_appv,appv)
          endif
        endif
    
      end subroutine grow_branch_plot_results_appv

 end module branch_plot_results_mod
 
!---------------------------------------------------------------------
 
 
 module make_mod
 
 contains
 
 subroutine  make1 ( size_app, size_v, res)
 
    use branch_plot_results_mod
    
    integer                                    , intent(in ) :: size_app  ! size of overall app array
    integer                                    , intent(in ) :: size_v    ! size of each app element
    type(branch_plot_results_type), allocatable, intent(out) :: res
    
    call construct_branch_plot_results(res)
    call construct_branch_plot_results_appv(res%appv, size_app)
    
    do ii = 1, size_app
      allocate(res%appv(ii)%v               (size_v  ))
      res%appv(ii)%v                    = ii*100.
    enddo
    
    allocate(res%system_variables(size_v/2))
    res%system_variables(1:size_v/2)%val = ii*200.
 
 end subroutine
 
 end module
 
 
!---------------------------------------------------------------------
 
 program testy
 
    use branch_plot_results_mod
    use make_mod
    
    type(branch_plot_results_type), allocatable :: res1, res2
    integer ii
    
    call make1(20,30, res1)
    
    do ii = 1, 10000
      call make1(40,50, res2)
      call copy_branch_plot_results(res1, res2)
      call destroy_branch_plot_results(res2)
    enddo
    
    continue
       
end program

