module testSGInterp

    use testHelper
    use kdefs, only : TINY

    use shellGrid
    use shellInterp

    implicit none

    integer, parameter :: Npnt = 50
    integer, parameter :: sub_is = 13
    integer, parameter :: sub_ie = 17
    !integer, parameter :: sub_ie = 37
    integer, parameter :: sub_js = 17
    integer, parameter :: sub_je = 21
    !integer, parameter :: sub_je = 41
    type(ShellGrid_T) :: sh
    type(ShellGridVar_T) :: shVar_rand_corner
    character(len=strLen) :: checkMessage


    contains

    @before
	subroutine setup()
        real(rp), dimension(Npnt) :: thetas, phis
        real(rp) :: dth, dph
        real(rp) :: thetaL = 10.0 *PI/180.0  ! So we avoid pole
        integer :: i,j

        dth = (0.5*PI - thetaL) / (Npnt-1)
        dph = 2.0*PI / (Npnt-1)

        do i=1,Npnt
            thetas(i) = thetaL + (i-1)*dth
        enddo

        do j=1,Npnt
            phis(j) = (j-1)*dph
        enddo

	    call GenShellGrid(sh, thetas, phis,'shgrTest_loc', radO=1.1_rp)
        call initShellVar(sh, SHGR_CORNER, shVar_rand_corner)
        do j=shVar_rand_corner%jsv,shVar_rand_corner%jev
            do i=shVar_rand_corner%isv,shVar_rand_corner%iev
                shVar_rand_corner%data(i,j) = rand()
            enddo
        enddo

	end subroutine setup

    @after
	subroutine teardown()
        call deallocShellGrid(sh)	    
    end subroutine teardown

    @test
    subroutine testEquivDCell_CC()
        !! Checks to see if the dTheta and dPhi calculated in TSG_SG and TSC_pnt evaluate to the same quantities
        type(ShellGridVar_T) :: var_src  ! Contains source data
        type(ShellGridVar_T) :: var_thruSG, var_thruPnt  ! Interpolated via TSC_SG and directly through TSC_pnt

        integer :: i,j
        real(rp) :: diffSum = 0.0

        call initShellVar(sh, SHGR_CORNER, var_src)
        var_src%mask = .true.

        ! Try cell-centered first
        call initShellVar(sh, SHGR_CC, var_thruSG )
        call initShellVar(sh, SHGR_CC, var_thruPnt)
        var_thruSG%mask = .true.
        var_thruPnt%mask = .true.

        ! Make some random data
        do j=sh%jsg,sh%jeg+1
            do i=sh%isg,sh%ieg+1
                call random_number(var_src%data(i,j))
            enddo
        enddo

        call InterpShellVar_TSC_SG(sh, var_src, sh, var_thruSG)
        !$OMP PARALLEL DO default(shared) collapse(1) &
        !$OMP schedule(dynamic) &
        !$OMP private(i,j)
        do j=sh%jsg,sh%jeg
            do i=sh%isg,sh%ieg
                if (.not. var_thruPnt%mask(i,j)) cycle
                call InterpShellVar_TSC_pnt( \
                        sh, var_src,\
                        sh%thc(i), sh%phc(j),\
                        var_thruPnt%data(i,j) )
            enddo
        enddo
        call wrapJ_SGV(sh, var_thruPnt)

        ! Check diffs
        do j=sh%jsg,sh%jeg+1
            do i=sh%isg,sh%ieg+1
                diffSum = diffSum + abs(var_thruPnt%data(i,j) - var_thruSG%data(i,j))
            enddo
        enddo

        @assertLessThanOrEqual(diffSum, TINY, "TSC_SG and TSC_pnt results don't match for SHCC dest vars")
        continue
    end subroutine testEquivDCell_CC


    @test
    subroutine testEquivDCell_Corner()
        !! Checks to see if the dTheta and dPhi calculated in TSG_SG and TSC_pnt evaluate to the same quantities
        type(ShellGridVar_T) :: var_src  ! Contains source data
        type(ShellGridVar_T) :: var_thruSG, var_thruPnt  ! Interpolated via TSC_SG and directly through TSC_pnt

        integer :: i,j
        real(rp) :: diffSum = 0.0

        call initShellVar(sh, SHGR_CORNER, var_src)
        var_src%mask = .true.

        call initShellVar(sh, SHGR_CORNER, var_thruSG )
        call initShellVar(sh, SHGR_CORNER, var_thruPnt)
        var_thruSG%mask = .true.
        var_thruPnt%mask = .true.

        ! Make some random data
        do j=sh%jsg,sh%jeg+1
            do i=sh%isg,sh%ieg+1
                call random_number(var_src%data(i,j))
            enddo
        enddo

        call InterpShellVar_TSC_SG(sh, var_src, sh, var_thruSG)
        !$OMP PARALLEL DO default(shared) collapse(1) &
        !$OMP schedule(dynamic) &
        !$OMP private(i,j)
        do j=sh%jsg,sh%jeg+1
            do i=sh%isg,sh%ieg+1
                if (.not. var_thruPnt%mask(i,j)) cycle
                call InterpShellVar_TSC_pnt( \
                        sh, var_src,\
                        sh%th(i), sh%ph(j),\
                        var_thruPnt%data(i,j) )
            enddo
        enddo
        call wrapJ_SGV(sh, var_thruPnt)

        ! Check diffs
        do j=sh%jsg,sh%jeg+1
            do i=sh%isg,sh%ieg+1
                diffSum = diffSum + abs(var_thruPnt%data(i,j) - var_thruSG%data(i,j))
            enddo
        enddo

        @assertLessThanOrEqual(diffSum, TINY, "TSC_SG and TSC_pnt results don't match for SHCORNER dest vars")
        continue
    end subroutine testEquivDCell_Corner

    @test
    subroutine testParentToChild_sameLoc()
        type(ShellGrid_T   ) :: destGrid
        type(ShellGridVar_T) :: destVar  ! Contains source data

        integer :: iExtra = 0, jExtra=0
        integer, dimension(4) :: nGhosts

        if(shVar_rand_corner%loc==SHGR_CORNER .or. shVar_rand_corner%loc==SHGR_FACE_THETA) then
            iExtra = 1
        endif
        if(shVar_rand_corner%loc==SHGR_CORNER .or. shVar_rand_corner%loc==SHGR_FACE_PHI) then
            jExtra = 1
        endif

        nGhosts = (/sh%Ngn, sh%Ngs, sh%Ngw, sh%Nge/)

        call GenChildShellGrid(sh, destGrid, "testChild", nGhosts=nGhosts, sub_is=sub_is,sub_ie=sub_ie)
        call initShellVar(destGrid, shVar_rand_corner%loc, destVar)
        call InterpShellVar_ParentToChild(sh, shVar_rand_corner, destGrid, destVar)
        
        @assertEqual(shVar_rand_corner%data(sub_is:sub_ie+iExtra,:), destVar%data(destGrid%is:destGrid%ie+iExtra,:), "Sameloc case for InterpShellVar_Parent2child not copying properly.")

    end subroutine testParentToChild_sameLoc

end module testSGInterp
