module C_FUNC

#if defined(INCLUDE_CXX)

    INTERFACE
        SUBROUTINE get_surface_fluxes_esm(sfx, meteo, model_param, surface_param, numerics, constants, grid_size) BIND(C)
            use sfx_data
            USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_PTR
            IMPLICIT NONE
            INTEGER(C_INT) :: grid_size
            type(C_PTR), value :: sfx
            type(C_PTR), value :: meteo
            type(sfx_esm_param) :: model_param
            type(sfx_surface_param) :: surface_param
            type(sfx_esm_numericsTypeC) :: numerics
            type(sfx_phys_constants) :: constants
        END SUBROUTINE get_surface_fluxes_esm

        SUBROUTINE get_surface_fluxes_sheba(zeta, Rib, Re, B, z0_m, z0_t, Rib_conv_lim, &
            Cm, Ct, Km, Prt_inv, & 
            U, dT, Tsemi, dQ, h, in_z0_m, & 
            kappa, Pr_t_0_inv, & 
            alpha_m, alpha_h, & 
            a_m, a_h,         &
            b_m, b_h,         &
            c_h,              &
            Re_rough_min, & 
            B1_rough, B2_rough, & 
            B_max_land, B_max_ocean, B_max_lake, & 
            gamma_c, Re_visc_min, & 
            Pr_m, nu_air, g, & 
            maxiters_charnock, & 
            grid_size) BIND(C)
            USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT
            USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_FLOAT
            IMPLICIT NONE
            INTEGER(C_INT) :: grid_size, maxiters_charnock
            REAL(C_FLOAT)  :: kappa, Pr_t_0_inv, Pr_t_inf_inv, alpha_m, alpha_h, a_m, a_h, b_m, b_h, &
            c_h, Rib_max, Re_rough_min, B1_rough, B2_rough, B_max_land, B_max_ocean, & 
            B_max_lake, gamma_c, Re_visc_min, Pr_m, nu_air, g
            REAL(C_FLOAT), dimension(grid_size) :: U, dT, Tsemi, dQ, h, in_z0_m, zeta, Rib, Re, &
            Rib_conv_lim, z0_m, z0_t, B, Cm, Ct, Km, Prt_inv
        END SUBROUTINE get_surface_fluxes_sheba
    END INTERFACE

    contains

    subroutine set_c_struct_sfx_surface_param_values(surface_param)
        use sfx_data
        use sfx_surface
        implicit none
        type (sfx_surface_param), intent(inout) :: surface_param
        surface_param%surface_ocean = surface_ocean
        surface_param%surface_land = surface_land
        surface_param%surface_lake = surface_lake

        surface_param%gamma_c = gamma_c
        surface_param%Re_visc_min = Re_visc_min
        surface_param%h_charnock = h_charnock
        surface_param%c1_charnock = c1_charnock
        surface_param%c2_charnock = c2_charnock
        surface_param%Re_rough_min = Re_rough_min
        surface_param%B1_rough = B1_rough
        surface_param%B2_rough = B2_rough
        surface_param%B3_rough = B3_rough
        surface_param%B4_rough = B4_rough
        surface_param%B_max_lake = B_max_lake
        surface_param%B_max_ocean = B_max_ocean
        surface_param%B_max_land = B_max_land
    end subroutine set_c_struct_sfx_surface_param_values

    subroutine set_c_struct_sfx_phys_constants_values(constants)
        use sfx_data
        use sfx_phys_const
        implicit none
        type (sfx_phys_constants), intent(inout) :: constants
        constants%Pr_m = Pr_m
        constants%g = g
        constants%nu_air = nu_air
    end subroutine set_c_struct_sfx_phys_constants_values
#endif
end module C_FUNC

