import sys
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
#from calendar_form import Ui_MainWindow
from category_window import Ui_CategoryWindow
from PyQt5 import uic

MW_Ui, MW_Base = uic.loadUiType('calendar_form.ui')


class CategoryWindow(qtw.QWidget):

    submitted = qtc.pyqtSignal(str)

    def __init__(self):
        super().__init__()
        # using the ui object method
        self.ui = Ui_CategoryWindow()
        self.ui.setupUi(self)
        self.show()

    @qtc.pyqtSlot()
    def on_submit_btn_clicked(self):
        # we can take advantage of connectSlotsByName here
        # to avoid explicit UI connections
        if self.ui.category_entry.text():
            self.submitted.emit(self.ui.category_entry.text())
        self.close()


#class MainWindow(qtw.QWidget, Ui_MainWindow):
class MainWindow(MW_Base, MW_Ui):
    events = {}

    def __init__(self):
        """MainWindow constructor. """
        super().__init__()
        self.setupUi(self)

        # disable the first category item
        self.event_category.model().item(0).setEnabled(False)

        ##################
        # Connect Events #
        ##################

        # disable time when "all day" is checked.
        # This is done for us in the UI file
        #self.allday_check.stateChanged.connect(self.event_time.setDisabled)

        # Populate the event list when the calendar is clicked
        self.calendar.selectionChanged.connect(self.populate_list)

        # Populate the event form when an item is selected
        self.event_list.itemSelectionChanged.connect(self.populate_form)

        # Save event when save is hit
        self.add_button.clicked.connect(self.save_event)

        # connect delete button
        self.del_button.clicked.connect(self.delete_event)

        # Enable 'delete' only when an event is selected
        self.event_list.itemSelectionChanged.connect(
            self.check_delete_btn)
        self.check_delete_btn()

        # check for selection of "new…" for category
        self.event_category.currentTextChanged.connect(self.on_category_change)

        self.show()

    def clear_form(self):
        self.event_title.clear()
        self.event_category.setCurrentIndex(0)
        self.event_time.setTime(qtc.QTime(8, 0))
        self.allday_check.setChecked(False)
        self.event_detail.setPlainText('')

    def populate_list(self):
        self.event_list.clear()
        self.clear_form()
        date = self.calendar.selectedDate()
        for event in self.events.get(date, []):
            time = (
                event['time'].toString('hh:mm')
                if event['time']
                else 'All Day'
            )
            self.event_list.addItem(f"{time}: {event['title']}")

    def populate_form(self):
        self.clear_form()
        date = self.calendar.selectedDate()
        event_number = self.event_list.currentRow()
        if event_number == -1:
            return

        event_data = self.events.get(date)[event_number]

        self.event_category.setCurrentText(event_data['category'])
        if event_data['time'] is None:
            self.allday_check.setChecked(True)
        else:
            self.event_time.setTime(event_data['time'])
        self.event_title.setText(event_data['title'])
        self.event_detail.setPlainText(event_data['detail'])

    def save_event(self):
        event = {
            'category': self.event_category.currentText(),
            'time': (
                None
                if self.allday_check.isChecked()
                else self.event_time.time()
                ),
            'title': self.event_title.text(),
            'detail': self.event_detail.toPlainText()
            }

        date = self.calendar.selectedDate()
        event_list = self.events.get(date, [])
        event_number = self.event_list.currentRow()

        # if no events are selected, this is a new event
        if event_number == -1:
            event_list.append(event)
        else:
            event_list[event_number] = event

        event_list.sort(key=lambda x: x['time'] or qtc.QTime(0, 0))
        self.events[date] = event_list
        self.populate_list()

    def delete_event(self):
        date = self.calendar.selectedDate()
        row = self.event_list.currentRow()
        del(self.events[date][row])
        self.event_list.setCurrentRow(-1)
        self.clear_form()
        self.populate_list()

    def check_delete_btn(self):
        self.del_button.setDisabled(self.event_list.currentRow() == -1)

    def on_category_change(self, text):
        if text == 'New…':
            self.dialog = CategoryWindow()
            self.dialog.submitted.connect(self.add_category)
            self.event_category.setCurrentIndex(0)

    def add_category(self, category):
        self.event_category.addItem(category)
        self.event_category.setCurrentText(category)

if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)

    # it's required to save a reference to MainWindow.
    # if it goes out of scope, it will be destroyed.
    mw = MainWindow()
    sys.exit(app.exec())