!  Copyright (C) 2019 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/>.

! this is a wrapper function to call C. Yong's DL_FIELD and avoid the generic C function name "main()"
! you.lu@stfc.ac.uk
! May 2018

module ChemShellDLFieldModule

    use, intrinsic :: iso_c_binding
    use DL_PY2F

    interface
        integer(c_int) function dl_field_c_main() bind(c, name='main')
            use iso_c_binding
        endfunction dl_field_c_main
    endinterface

    private
    public :: PyOptions, natoms, nqmatoms, nexcludes

    type(dictType), pointer :: PyOptions
    integer                 :: natoms, nqmatoms, nexcludes

    contains

    integer(c_int) function dl_field_main(optionsPtr, c_natoms, c_nqmatoms, c_nexcludes) bind(c, name='dl_field_main') result(ierror)
    
        type(PyType)  , intent(in) :: optionsPtr
        integer(c_int), intent(in) :: c_natoms
        integer(c_int), intent(in) :: c_nqmatoms
        integer(c_int), intent(in) :: c_nexcludes

        natoms    = c_natoms
        nqmatoms  = c_nqmatoms
        nexcludes = c_nexcludes

        allocate(PyOptions, source=ptr2dict(optionsPtr))

        ierror = dl_field_c_main()
        call flush(6)
    
    endfunction dl_field_main
    integer(c_int) function dl_field_finalise() bind(c) result(ierror)

        ! YL 09/07/2019: segfaults
        deallocate(PyOptions)

        ierror = 0

    endfunction dl_field_finalise
! not in use
!    integer(c_int) function get_dl_field_path() bind(c) result(ierror)
!
!!        character(kind=c_char), pointer, intent(out) :: dl_field_path(:)
!
!        character(len=255)                  :: cbuff
!        character(len=:)      , pointer     :: c
!        character(kind=c_char), target      :: ccbuff(255)
!        integer                             :: i
!
!        ccbuff(:) = " "
!
!        cbuff = '@DL_FIELD@/chemsh/dl_field/dl_f_path'//C_NULL_CHAR
!        do i = 1, len(trim(cbuff))
!            ccbuff(i) = cbuff(i:i)
!        enddo
!
!!        allocate(dl_field_path(255), source=ccbuff)
!!        dl_field_path => ccbuff
!!        print *, "### get_dl_field_path: dl_field_path =", dl_field_path
!        call PyOptions%get('dl_field_path', c)
!        print *, "### get_dl_field_path: get dl_field_path =", c
!        call PyOptions%set('dl_field_path', ccbuff)
!        call flush(6)
!
!        ierror = 0
!
!    endfunction get_dl_field_path
    integer(c_int) function dl_field_get_chemsh_path(chemsh_path) bind(c, name='chemsh_get_path') result(ierror)
     
        character(kind=c_char), intent(out) :: chemsh_path(255)
    
        character(len=255)                  :: cbuff
        integer                             :: i

        chemsh_path(:) = " "

        cbuff = '@CHEMSH_DIR@/chemsh/interfaces/dl_field/dl_f_path'//C_NULL_CHAR
        do i = 1, len(trim(cbuff))
            chemsh_path(i) = cbuff(i:i)
        enddo

        ierror = 0
    
    endfunction dl_field_get_chemsh_path
    integer(c_int) function dl_field_set_path_lib(path_lib) bind(c, name='chemsh_set_dlf_path_lib') result(ierror)
     
        character(kind=c_char), intent(out) :: path_lib(255)
    
        character(len=255)                  :: cbuff
        character(len=:)  , pointer         :: pcbuff
        integer                             :: i

        call PyOptions%get('path_lib' , pcbuff)
        do i = 1, 255
            path_lib(i) = pcbuff(i:i)
        enddo

        ! lib_path: Library_path in dl_field.c
        if(all(path_lib.eq."")) then
            cbuff = '@DL_FIELD_ABSOLUTE@/lib'//C_NULL_CHAR
            do i = 1, len(trim(cbuff))
                path_lib(i) = cbuff(i:i)
            enddo
        endif

        ierror = 0
    
    endfunction dl_field_set_path_lib
    integer(c_int) function dl_field_set_path_sol(path_sol) bind(c, name='chemsh_set_dlf_path_sol') result(ierror)

        character(kind=c_char), intent(out) :: path_sol(255)

        character(len=255)                  :: cbuff
        character(len=:)  , pointer         :: pcbuff
        integer                             :: i

        call PyOptions%get('path_sol' , pcbuff)
        do i = 1, 255
            path_sol(i) = pcbuff(i:i)
        enddo

        ! path_sol: Solvent_path in dl_field.c
        if(all(path_sol.eq."")) then
            cbuff = '@DL_FIELD_ABSOLUTE@/solvent'//C_NULL_CHAR
            do i = 1, len(trim(cbuff))
                path_sol(i) = cbuff(i:i)
            enddo
        endif

        ierror = 0

    endfunction dl_field_set_path_sol
    integer(c_int) function dl_field_set_path_out(path_out) bind(c, name='chemsh_set_dlf_path_out') result(ierror)

        character(kind=c_char), intent(out) :: path_out(255)

        character(len=255)                  :: cbuff
        character(len=:)  , pointer         :: pcbuff
        integer                             :: i

        call PyOptions%get('path_out' , pcbuff)
        do i = 1, 255
            path_out(i) = pcbuff(i:i)
        enddo

        ! lib_out: Output_path in dl_field.c
        if(all(path_out.eq."")) then
            cbuff = '@DL_FIELD_ABSOLUTE@/output'//C_NULL_CHAR
            do i = 1, len(trim(cbuff))
                path_out(i) = cbuff(i:i)
            enddo
        endif

        ierror = 0

    endfunction dl_field_set_path_out

endmodule ChemShellDLFieldModule
