!  Copyright (C) 2017 The authors of Py-ChemShell
!
!  This file is part of Py-ChemShell.
!
!  Py-ChemShell is free software: you can redistribute it and/or modify
!  it under the terms of the GNU Lesser General Public License as
!  published by the Free Software Foundation, either version 3 of the
!  License, or (at your option) any later version.
!
!  Py-ChemShell is distributed in the hope that it will be useful,
!  but WITHOUT ANY WARRANTY; without even the implied warranty of
!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
!  GNU Lesser General Public License for more details.
!
!  You should have received a copy of the GNU Lesser General Public
!  License along with Py-ChemShell.  If not, see
!  <http://www.gnu.org/licenses/>.

module ChemShellGAMESSUKModule

    use, intrinsic :: iso_c_binding
    use DL_PY2F
    use ChemShellParallelModule

    private

    public register_gamess_uk, interface_gamess_uk
!    public PyFrag, PyShells, nshells

    type(dictType) , pointer :: PyFrag, PyShells
    integer                  :: nshells
    integer(c_int)           :: c_debug
    integer(c_int)           :: gamess_uk_handle
    integer                  :: first_time_run = 1

    contains

      
    subroutine register_gamess_uk(debug) bind(c, name="f_register_gamess_uk")

        use ChemShellParallelModule, only : chemsh_parallel

        integer(c_int), intent(in) :: debug

        type(c_funptr)             :: gamess_uk_pointer

        c_debug = debug
        gamess_uk_pointer = c_funloc(gamess_uk_wrap)
        gamess_uk_handle = chemsh_parallel%get_function_handle(gamess_uk_pointer)

    endsubroutine register_gamess_uk
    ! called by master process only
    subroutine interface_gamess_uk(fragPtr) bind(c)
 
        use ChemShellParallelModule, only : chemsh_parallel

        implicit none
 
        type(PyType)  , intent(in) :: fragPtr
 
        integer                    :: ierror
        type(PyType)  , pointer    :: shellsPtr
 
        ! set up dict of fragObj
        allocate(PyFrag, source=ptr2dict(fragPtr))
        call PyFrag%get('shells', shellsPtr)
 
        ! set up dict of shellsObj and save nshells
        allocate(PyShells, source=ptr2dict(shellsPtr))
        call PyShells%get('npts', nshells)
 
        if(chemsh_parallel%is_parallel()) then
           ierror = chemsh_parallel%exec_function(gamess_uk_handle, c_debug)
        else
           ierror = gamess_uk_wrap()
        endif
 
        deallocate(PyFrag, PyShells)
 
    endsubroutine interface_gamess_uk


    ! also called by slave processes
    integer function gamess_uk_wrap() result(ierror)

        ! first_time_run = 1 should only be applied at the first time ChemShell invokes GAMESS-UK,
        ! otherwise it cannot be run over 100 times (see pg_begin() in GAMESS-UK/m4/parallel.m)
        !call chemsh_gamess(first_time_run, ierror)
        call gamess(first_time_run, ierror)

        call flush(6)

        first_time_run = 0

    endfunction gamess_uk_wrap

endmodule ChemShellGAMESSUKModule

