import warnings


def compute_cell_param(X, ar_Xc, Dt, alpha_s, alpha_o,
                       alpha_c, nb_cell, A_thres, W_max,
                       W_min, ar_lambda, ar_tan_beta,
                       ar_tan_beta_channel, ar_L, ar_Ks,
                       ar_theta_r, ar_theta_s, ar_n_o,
                       ar_n_c, ar_A_drained):
    """Compute model parameters from physical parameters.

    This function uses the physically based parameters and constraints
    for each model cell to compute, the saturated soil moisture
    volume, channel width and constant terms for the differential
    equations of the soil, overland and channel stores.

    Parameters
    ----------
    X : scalar
        The lateral dimension of the grid-cell (:math:`m`)
    ar_Xc : (N,) float array
        The length of the channel in a cell, this can be different
        from the lateral dimension of the grid cell if the channel
        runs along the cell diagonal (:math:`m`)
    Dt : scalar
        The length of the current time-step in seconds
    alpha_s : scalar
        The dimensionless pore-size distribution parameter for the
        soil store
    alpha_o : scalar
        Power co-efficient for Mannings Equation applied to the
        overland store the value is typically 5/3
    alpha_c : scalar
        Power co-efficient for Mannings Equation applied to the
        channel store the value is typically 5/3
    nb_cell : scalar
        The number of cells in the catchment
    A_thres : scalar
        The minimum area of upstream contributing cells required
        before a cell is considered to initiate a river channel
        (:math:`m^2`)
    W_min : scalar
        The minimum width of a channel (:math:`m`)
    W_max : scalar
        The maximum width of a channel (:math:`m`)
    ar_lambda : (N,) int array
        Switch indicating whether the current cell contains a
        channel. A value of `1` indicates a channel cell, `0`
        indicates no channel
    ar_tan_beta : (N,) float array
        The tangent of the surface slope for each cell. The surface
        slope affects processes in the overland and soil stores
    ar_tan_beta_channel : (N,) float array
        The tangent of the channel slope for each cell. This is
        conceptually different from the surface slope and affects the
        channel store
    ar_L : (N,) float array
        The depth of the soil store in each cell (:math:`m`)
    ar_Ks : (N,) float array
        The saturated hydraulic conductivity of each cell
        (:math:`mm/s`)
    ar_theta_r : (N,) float array
        The residual soil moisture content for each cell
    ar_theta_s : (N,) float array
        The saturated soil moisture content for each cell
    ar_n_o : (N,) float array
        Manning's roughness coefficient for overland flows in each
        cell
    ar_n_c : (N,) float array
        Manning's roughness coefficient for channel flows in each cell
    ar_A_drained : (N,) float array
        The total drained area associated with each cell (:math:`m^2`)

    Returns
    -------
    ar_Vsm : (N,) float array
        The saturated moisture volume of the soil store for each cell
        (:math:`m^3`)
    ar_b_s : (N,) float array
        The constant term of the non differential equation for each
        soil store --> :math:`dV_s/dt = a_s - b_s V_s^{\\alpha_s}`
    ar_b_o : (N,) float array
        The constant term of the non differential equation for each
        overland store --> :math:`dV_o/dt = a_o - b_o V_o^{\\alpha_o}`
    ar_W : (N,) float array
        The channel width for each cell (:math:`m`)
    ar_b_c : (N,) float array
        The constant term of the non differential equation for each
        channel store --> :math:`dV_c/dt = a_c - b_c V_c^{\\alpha_c}`

    """
    ##Soil parameters
    ar_Vsm=(ar_theta_s-ar_theta_r)*(X**2)*ar_L
    ar_Cs=(ar_L*ar_Ks*ar_tan_beta)/(((ar_theta_s-ar_theta_r)*ar_L)**alpha_s)
    ar_b_s=ar_Cs*X/(X**(2*alpha_s))
    ##Overland parameters
    ar_Co=(1/ar_n_o)*(ar_tan_beta)**0.5
    ar_b_o=ar_Co*X/(X**(2*alpha_o))
    ##Channel parameters
    A_total=nb_cell*X**2
    ar_W = W_max + ((W_max-W_min)/(A_total**0.5-A_thres**0.5)) \
           * (ar_A_drained**0.5-A_total**0.5)

    with warnings.catch_warnings():
        # Cells without channel stores cause harmless zero-division errors
        warnings.filterwarnings('ignore',
                                r'divide by zero encountered in true_divide')

        ar_Cc=(1/ar_n_c)*(ar_tan_beta_channel)**0.5

    ar_b_c=ar_Cc*ar_W/((ar_Xc*ar_W)**(alpha_c))
    ar_W[ar_lambda==0]=-99.9
    ar_b_c[ar_lambda==0]=-99.9

    return ar_Vsm, ar_b_s, ar_b_o, ar_W, ar_b_c