! See copyright notice in the COPYRIGHT file.
! ****************************************************************************** !
!> This module contains the definition of geometry type

module mus_geom_module

  ! include treelm modules
  use treelmesh_module,        only: treelmesh_type
  use tem_property_module,     only: prp_hasBnd, prp_hasQVal
  use tem_bc_prop_module,      only: tem_bc_prop_type
  use tem_geometry_module,     only: tem_build_treeToProp_pointer
  use tem_logging_module,      only: logUnit

  ! include musubi modules
  use mus_geomIncrHead_module, only: mus_geomIncrHead_type

  implicit none

  private

  public :: mus_geom_type
  public :: mus_build_posInProp

  !> Geometric information and definitions
  type mus_geom_type

    !> tree data type
    type( treelmesh_type ) :: tree

    !> boundary information as stored on disk
    type( tem_bc_prop_type ) :: boundary

    !> The header type containing all the geometry increase information
    type( mus_geomIncrHead_type ), allocatable :: geomIncr(:)

    !> Logical to define whether geometry increase is active or not
    logical :: dynamicGeom = .false.

    !> Tree element position in the boundary_ID( nDir, nElems) in bc_prop_type
    !! it has a size of tree%nElems
    !! How to use:
    !! do iElem = 1, tree%nElems
    !!   posInBndID = posInBndID( iElem )
    !!   ! current element has boundary only if posInBndID>0 
    !!   ! else posInBndID = -1
    !!   if (posInBnd > 0 )
    !!     bnd_ID(1:nDir) = bc_prop%boundary_ID( 1:nDir, posInBndID )
    !!   end if
    !! end do
    integer, allocatable :: posInBndID(:)

    !> Tree element position in the qVal( nDir, nElems) in bc_prop_type
    !! it has a size of tree%nElems
    !! How to use:
    !! do iElem = 1, tree%nElems
    !!   posInQVal = posInQVal( iElem )
    !!   ! current element has qVal if posInQVal>0 else posInQVal = -1
    !!   if (posInQVal > 0 )
    !!     qVal(1:nDir) = bc_prop%qVal( 1:nDir, posInQVal )
    !!   end if
    !! end do
    integer, allocatable :: posInQVal(:)

    !> tree element position in level descriptor total list
    !! it has a size of tree%nElems
    !! How to use:
    !! do iElem = 1, tree%nElems
    !!   treeID = tree%treeID( iElem )
    !!   level = tem_levelOf( treeID )
    !!   posInTotal = levelPointer( iElem )
    !!   treeID = LevelDesc( iLevel )%total( posInTotal )
    !! end do
    integer, allocatable :: levelPointer(:)

  end type mus_geom_type

contains

  subroutine mus_build_posInProp( me )
    ! --------------------------------------------------------------------------
    type( mus_geom_type ), intent(inout) :: me !< Treelmesh data
    ! --------------------------------------------------------------------------
    integer :: iProp
    ! --------------------------------------------------------------------------

    do iProp = 1, me%tree%global%nProperties
      if( me%tree%global%property( iProp )%nElems > 0 ) then
        select case( me%tree%global%property( iProp )%bitpos )
        case( prp_hasBnd )
          if (  allocated( me%posInBndID )) deallocate( me%posInBndID )
          allocate( me%posInBndID(me%tree%nElems) )
          ! build me%posInBnd which maps tree to boundary%boundary_ID
          call tem_build_treeToProp_pointer( &
            &        treeToProp = me%posInBndID, &
            &        nElems     = me%tree%nElems,&
            &        ElemPropertyBits = me%tree%ElemPropertyBits,&
            &        prp_bit    = prp_hasBnd           )

        case( prp_hasQVal )
          if ( allocated( me%posInQval )) deallocate( me%posInQval )
          allocate( me%posInQval(me%tree%nElems) )
          ! build me%posInQVal which maps tree to boundary%qVal
          call tem_build_treeToProp_pointer( &
            &        treeToProp = me%posInQVal, &
            &        nElems     = me%tree%nElems,&
            &        ElemPropertyBits = me%tree%ElemPropertyBits,&
            &        prp_bit    = prp_hasQVal         )

        end select ! property( iProp )%bitpos
      endif ! property( iProp )%nElems > 0
    enddo ! iProp

  end subroutine mus_build_posInProp

end module mus_geom_module
! ****************************************************************************** !
