from Tkinter import Frame, Label

from src.view.custom_widgets.AddIncomeWindow import AddIncomeWindow
from src.view.custom_widgets.TitleLabelWithAddRemoveButtons import TitleLabelWithAddRemoveButtons
from src.view.custom_widgets.RemoveFromTableWindow import RemoveFromTableWindow
from src.view.custom_widgets.AddItemWindow import AddItemWindow

class GUITable(Frame):
    """
    This class is used as a super class for any table with a title, nrows number of rows, ncols number of columns,
    and an add button.
    """

    INCOME = "INCOME"
    ITEM = "ITEM"
    ADD = "ADD"
    REMOVE = "REMOVE"

    def __init__(self, controller, title, category, nrows, ncols, init_items, column_labels, width, parent=None):
        """
        Initialize the GUITable
        :param title: title of the table
        :param nrows: number of rows
        :param ncols: number of columns
        :param init_items: list of tuples representing initial items (one tuple per row -- first value must be key to be hidden)
        :param parent: parent
        """
        Frame.__init__(self, parent, width=width, background="black")
        self.controller = controller
        self.title = title
        self.nrows = nrows + 2
        self.ncols = ncols
        self.items = init_items
        self.col_width = width / ncols
        self.col_labels = column_labels
        self.parent = parent
        self.category = category
        self.initialize_table()

    def initialize_table(self):
        """
        Initialize table with a title label and a grid w/ the initial items
        :return: None.
        """
        TitleLabelWithAddRemoveButtons(self.title, self.ncols * self.col_width, self.open_add_item_window,
                                       self.open_remove_item_window, self).grid(row=0, column=0, columnspan=self.ncols)

        for c in xrange(0, self.ncols):
            Label(self, text=self.col_labels[c], bg="#969494",
                  width=self.col_width).grid(row=1, column=c, padx=1, pady=1)

        self.fill_table()

    def fill_table(self):
        for r in xrange(0, self.nrows):
            if r < len(self.items):
                item = self.items[r]
            else:
                item = ['' for col in range(self.ncols + 1)]
            for c in xrange(1, self.ncols + 1):
                Label(self, text=item[c], width=self.col_width).grid(row=r+2, column=c-1, padx=1, pady=1)

    def open_add_item_window(self):
        if self.category == self.INCOME:
            AddIncomeWindow(self.add_item)
        elif self.category == self.ITEM:
            AddItemWindow(self.add_item)

    def add_item(self, item_values):
        key = self.notify_controller(self.ADD, item_values)
        if key != "":
            self.items.append(tuple([key] + [i for i in item_values]))
            self.fill_table()

    def open_remove_item_window(self):
        RemoveFromTableWindow("Which one would you like to remove?", [(i[0], i[1]) for i in self.items], self.remove_item)

    def remove_item(self, item_key):
        """

        :param item_key:
        :return: item_key
        """
        for i in xrange(0, len(self.items)):
            if self.items[i][0] == item_key:
                self.items.pop(i)
                self.fill_table()
                return self.notify_controller(self.REMOVE, item_key)

    def notify_controller(self, action_type, item_info):
        """
        Notifies the controller when the state changes
        :return: item key
        """
        return self.controller.items_update_from_user(action_type + " " + self.category,
                                               item_info)


