class DataVisualizer(tkinter.LabelFrame):
    def __init__(self, parent, **optional_arguments):
        tkinter.LabelFrame.__init__(self,
                                    parent,
                                    text=optional_arguments['text'])
        self.colors = None

        # setup default parameters and then process optional arguments
        self.field_count = default_field_count
        self.process_optional_arguments(optional_arguments)

        # setup the table showing initial balance, current balance, and expenditure totals
        self.totals_table: TableWidget = None
        self.load_total_amounts()

        # sets up a separator between the two tables
        separator = Separator(self)
        separator.grid(row=0, column=1, sticky="NS")

        # setup the table showing spending by category
        self.category_table: TableWidget = None
        self.load_spending_by_category()

        # setup the pie chart
        self.pie_chart = PieChart(self)
        self.pie_chart.grid(row=1, columnspan=3)

        self.load_table_data(None, None, None)

    def process_optional_arguments(self, optional_arguments):
        if 'field_count' in optional_arguments.keys():
            self.field_count = optional_arguments['field_count']

    def load_spending_by_category(self):
        self.category_table = TableWidget(self,
                                          2,
                                          self.field_count,
                                          head_font=default_table_head_font,
                                          entry_font=default_entry_font,
                                          entry_justify_list=["right", "left"],
                                          head_justify_list=["right", "left"])
        self.category_table.hide_config_buttons()
        self.category_table.set_header_values(['Category', 'Amount'])
        self.category_table.grid(row=0, column=2)

    def load_total_amounts(self):
        self.totals_table = TableWidget(
            self,
            3,
            1,
            entry_font=default_entry_font,
            entry_justify=["left"],
            head_justify_list=["right", "right", "right"],
            invert_axis=True)
        self.totals_table.hide_config_buttons()
        self.totals_table.set_header_values(
            ["Initial Total", "Expenditure Total", "Current Total"])
        self.totals_table.grid(row=0, column=0)

    def load_table_data(self, expenditures_by_type: [[]], initial_balances,
                        current_balances):
        self.load_expenditure_data(expenditures_by_type)
        self.load_totals_data(initial_balances, expenditures_by_type,
                              current_balances)
        self.update_colors()

    def load_expenditure_data(self, expenditures_by_type: [[]]):
        if expenditures_by_type is not None and expenditures_by_type != []:
            labels = []
            values = []
            table = []
            for row_index in range(len(expenditures_by_type)):
                labels.append(expenditures_by_type[row_index][0])
                values.append(expenditures_by_type[row_index][1])
                table.append([
                    expenditures_by_type[row_index][0],
                    TableWidget.format_as_currency(
                        expenditures_by_type[row_index][1])
                ])
            self.category_table.load_table_data(table)
            self.pie_chart.construct_pie_chart(
                labels, values, text_col=self.pie_chart.label_text_col)
        else:
            self.category_table.clear_labels()
            self.pie_chart.construct_empty_chart()

    def load_totals_data(self, initial_balances, expenditures_by_type,
                         current_balances):
        if expenditures_by_type is not None and expenditures_by_type != []:
            total_spending = 0
            for row in expenditures_by_type:
                total_spending += row[1]
            spending_text = TableWidget.format_as_currency(total_spending)
            self.totals_table.set_value(spending_text, 0, 1)
        else:
            self.totals_table.set_value("-", 0, 1)

        if initial_balances is not None and initial_balances != []:
            total_initial_balance = 0
            for balance in initial_balances:
                total_initial_balance += balance[2]
            initial_text = TableWidget.format_as_currency(
                total_initial_balance)
            self.totals_table.set_value(initial_text, 0, 0)
        else:
            self.totals_table.set_value("-", 0, 0)

        if current_balances is not None and current_balances != []:
            total_current_balance = 0
            for balance in current_balances:
                total_current_balance += balance[2]
            current_text = TableWidget.format_as_currency(
                total_current_balance)
            self.totals_table.set_value(current_text, 0, 2)
        else:
            self.totals_table.set_value("-", 0, 2)

    def set_colors(self, color_dict: {str: str}):
        self.colors = color_dict
        self.update_colors()

    def update_colors(self):
        if self.colors is not None:
            self.config(bg=self.colors['bg_col'], fg=self.colors['text_col'])
            self.pie_chart.set_colors(self.colors['pie_chart_colors'])
            self.category_table.set_colors(
                self.colors['category_table_colors'])
            self.totals_table.set_colors(self.colors['totals_table_colors'])