from typing import Dict
import shutil


def dt_calc_table_width(min_widths: Dict[str, int], pad: bool, border: bool,
                        table_width: int) -> int:
    """Calculate the width of the table based on all of the table parameters
    and column min widths.

    :param min_widths: Minimum column width by column.
    :param pad: Whether to pad each column with a space on either side
        of the divider.
    :param border: Whether the tables has a border.
    :param table_width: The user specified table width.
    """

    fields = list(min_widths.keys())

    # Add divider widths
    divider_size = 3 if pad else 1
    deco_size = divider_size * (len(fields) - 1)
    # Add the side spacing
    deco_size += 2 if pad else 0
    # Add border widths
    if border:
        border_size = 2 if pad else 1
        deco_size += border_size * 2

    # Gets the effective window width.
    if table_width is None:
        table_width = shutil.get_terminal_size().columns
        table_width = 80 if table_width == 0 else table_width
    table_width -= deco_size

    # Makes sure window is at least large enough to display our smallest
    # possible table
    total_min = sum(min_widths.values())
    if total_min > table_width:
        table_width = total_min

    return table_width