def __init__(self, parent=None):

        super().__init__(parent)

        self.form = WienwahlView.Ui_MainWindow()
        self.form.setupUi(self)

        self.dialogWindow = DatabaseDialogController()

        self.model = WienwahlModel()

        self.handler = {}
        self.handler["csvHandler"] = CSVHandler()
        self.handler["databaseHandler"] = DatabaseHandler('mysql+pymysql://wienwahl:wienwahl@localhost/wienwahl?charset=utf8')

        self.databaseStep = None

        self.threads = []


        self.form.newFile.triggered.connect(self.newFile)
        self.form.openFile.triggered.connect(self.openFile)
        self.form.saveFile.triggered.connect(self.saveResourceThread)
        self.form.saveAsFile.triggered.connect(self.saveAsFile)
        self.form.saveAsDatabase.triggered.connect(self.saveAsDatabase)
        self.form.openDatabase.triggered.connect(self.openDatabase)
        self.form.copy.triggered.connect(self.copy)
        self.form.cut.triggered.connect(self.cut)
        self.form.paste.triggered.connect(self.paste)
        self.form.undo.triggered.connect(self.undo)
        self.form.redo.triggered.connect(self.redo)
        self.form.closeWindow.triggered.connect(self.closeWindow)
        self.form.helpWindow.triggered.connect(self.helpWindow)
        self.form.tabs.currentChanged.connect(self.tabChanged)
        self.form.tabs.tabCloseRequested.connect(self.closeTab)
        self.form.addRow.triggered.connect(self.addRow)
        self.form.duplicateRow.triggered.connect(self.duplicateRow)
        self.form.removeRow.triggered.connect(self.removeRows)

        self.form.prediction.triggered.connect(self.prediction)
        self.form.createPrediction.triggered.connect(self.createPrediction)
class MyController(QMainWindow):
    def __init__(self, parent=None):

        super().__init__(parent)

        self.form = WienwahlView.Ui_MainWindow()
        self.form.setupUi(self)

        self.dialogWindow = DatabaseDialogController()

        self.model = WienwahlModel()

        self.handler = {}
        self.handler["csvHandler"] = CSVHandler()
        self.handler["databaseHandler"] = DatabaseHandler('mysql+pymysql://wienwahl:wienwahl@localhost/wienwahl?charset=utf8')

        self.databaseStep = None

        self.threads = []


        self.form.newFile.triggered.connect(self.newFile)
        self.form.openFile.triggered.connect(self.openFile)
        self.form.saveFile.triggered.connect(self.saveResourceThread)
        self.form.saveAsFile.triggered.connect(self.saveAsFile)
        self.form.saveAsDatabase.triggered.connect(self.saveAsDatabase)
        self.form.openDatabase.triggered.connect(self.openDatabase)
        self.form.copy.triggered.connect(self.copy)
        self.form.cut.triggered.connect(self.cut)
        self.form.paste.triggered.connect(self.paste)
        self.form.undo.triggered.connect(self.undo)
        self.form.redo.triggered.connect(self.redo)
        self.form.closeWindow.triggered.connect(self.closeWindow)
        self.form.helpWindow.triggered.connect(self.helpWindow)
        self.form.tabs.currentChanged.connect(self.tabChanged)
        self.form.tabs.tabCloseRequested.connect(self.closeTab)
        self.form.addRow.triggered.connect(self.addRow)
        self.form.duplicateRow.triggered.connect(self.duplicateRow)
        self.form.removeRow.triggered.connect(self.removeRows)

        self.form.prediction.triggered.connect(self.prediction)
        self.form.createPrediction.triggered.connect(self.createPrediction)

    def openFileDialog(self):
        """
        Opens a file dialog and sets the label to the chosen path
        """

        path, _ = QFileDialog.getOpenFileName(self, "Open File", os.getcwd())
        return path


    def newFileDialog(self):
        path, _ = QFileDialog.getSaveFileName(self, "Save File", os.getcwd())
        return path

    def closeDatabaseDialog(self):
        self.dialogWindow.hide()


    def newFile(self):
        self.generateNewTab([["T","WV","WK","BZ","SPR","WBER","ABG","UNG","SPOE","FPOE","OEVP","GRUE","NEOS","WWW","ANDAS","GFW","SLP","WIFF","M","FREIE"]], None)

    def formatTable(self, table):
        # set font
        font = QFont("Courier New", 14)
        table.setFont(font)
        # set column width to fit contents (set font first!)
        table.resizeColumnsToContents()
        # enable sorting
        if self.model.getCurrentTable().getContent():
            table.setSortingEnabled(True)


    def appendTab(self, accessor):
        tab = QtGui.QWidget()
        tab.setObjectName("tab"+str(self.model.getTableCount()))
        if accessor:
            tab.setToolTip(accessor.getAccessString())
            self.form.tabs.addTab(tab, accessor.getName())
        else:
            tab.setToolTip("New")
            self.form.tabs.addTab(tab, "New")
        self.form.tabs.setCurrentIndex(self.form.tabs.count()-1)
        return tab

    def appendTable(self, table_model, parent):
        table_view = QTableView()
        table_view.setObjectName("table"+str(self.model.getTableCount()))
        table_view.setModel(table_model)
        table_view.setItemDelegate(ItemDelegate(table_model.getUndoStack(), self.editedSomething))

        layout = QVBoxLayout(self)
        layout.addWidget(table_view)
        parent.setLayout(layout)

        return table_view

    def generateNewTab(self, content, accessor):
            tab = self.appendTab(accessor)

            table_model = TableModel(tab, content, accessor)

            self.model.setCurrentTableAndAdd(table_model)
            table_view = self.appendTable(table_model, tab)
            self.formatTable(table_view)
            self.model.getCurrentTable().setView(table_view)
            self.model.getCurrentTable().setEdited(False)

    def openFile(self):
        path = self.openFileDialog()
        if path is not "":
            accessor = Accessor(path, ConnectionType.csv)
            self.generateNewTab(self.handler["csvHandler"].getContentAsArray(accessor.getAccessString()), accessor)

    def databaseDialog(self):
        self.dialogWindow.setElections(self.handler["databaseHandler"].getElections())
        self.dialogWindow.show()
        if self.dialogWindow.exec_():
            self.dialogWindow.hide()
            return self.dialogWindow.getElection()

    def handleDatabase(self):
        pass

    def openDatabase(self):
        access = self.databaseDialog()
        if access:
            accessor = Accessor(access, ConnectionType.database)
            self.generateNewTab(self.handler["databaseHandler"].getVotesAsArray(accessor.getAccessString()), accessor)

    def saveAsResourceThread(self, type, append=False):
        self.saveAsResource(type, append)

    def saveResourceThread(self, accessor=None, data=None, append=False):
        self.saveResource(accessor, data, append)

    def setSavingStatus(self, saved, currentTable):
        if saved==True:
            self.form.statusbar.showMessage('saved')
            currentTable.setEdited(False)
            # print("Set saving status saved")
        else:
            self.form.statusbar.showMessage('saving...')
            # print("Set saving saving")

    def askForAppending(self):
        reply = QtGui.QMessageBox.question(self, 'Message', "Do want to append this content", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
        return reply == QtGui.QMessageBox.Yes


    def saveResource(self, accessor=None, data=None, append=False):
        if data or self.model.getCurrentTable() and self.model.getCurrentTable().getAccessor():
            saver = Saver(self.handler, self.model.getCurrentTable(), accessor, data, append)
            saver.updateProgress.connect(self.setSavingStatus)
            saver.start()
            self.threads.append(saver)

    def saveAsDatabase(self):
        append = self.askForAppending()
        self.saveAsResourceThread(ConnectionType.database, append)

    def saveAsFile(self):
        self.saveAsResourceThread(ConnectionType.csv)

    def saveAsResource(self, type=ConnectionType.csv, append=False):
        accessor = None
        if self.model.getTableCount()>0:
            if type==ConnectionType.csv:
                accessor = Accessor(self.newFileDialog(), ConnectionType.csv)
            elif type==ConnectionType.database:
                accessor = Accessor(self.databaseDialog(), ConnectionType.database)

            self.model.getCurrentTable().setAccessor(accessor)

            self.saveResourceThread(accessor, None, append)

            self.form.tabs.setTabText(self.model.getCurrentIndex(), accessor.getName())
            self.form.tabs.setTabToolTip(self.model.getCurrentIndex(), accessor.getName())

    def get_selected_rows(self):
        indexes = self.model.getCurrentTable().getView().selectionModel().selectedIndexes()
        if indexes:
            print(str(indexes[0].row()) + "amount:" + str(len(indexes)))
            return indexes[0].row(), len(indexes)
        else:
            return None, None


    def addRow(self):
        table = self.model.getCurrentTable()
        if table:
            start, amount = self.get_selected_rows()
            if amount:
                table.getUndoStack().beginMacro("Added table")
                table.getUndoStack().push(InsertRowsCommand(self.model.getCurrentTable(), start, 1))
                table.getUndoStack().endMacro()
                self.editedSomething()

    def duplicateRow(self):
        table = self.model.getCurrentTable()
        if len(table.getContent()) == 0:
            return
        start, amount = self.get_selected_rows()
        if amount:
            table.getUndoStack().beginMacro("Duplicated row")
            table.getUndoStack().push(DuplicateRowCommand(table, start))
            table.getUndoStack().endMacro()
            self.editedSomething()

    def removeRows(self):
        table = self.model.getCurrentTable()
        if len(table.getContent()) == 0:
            return
        start, amount = self.get_selected_rows()
        if amount:
            table.getUndoStack().beginMacro("Removed row(s)")
            table.getUndoStack().push(RemoveRowsCommand(table, start, amount))
            table.getUndoStack().endMacro()
            self.editedSomething()

    def cut(self):
        table = self.model.getCurrentTable()
        selectedIndexes = self.model.getCurrentTable().getView().selectionModel().selectedIndexes()
        if len(selectedIndexes) == 0:
            return

        sys_clip = QApplication.clipboard()
        selection = selectedIndexes[0]
        selected_text = str(self.model.getCurrentTable().data(selection))
        sys_clip.setText(selected_text)

        cmd = EditCommand(self.model.getCurrentTable(), selection)
        cmd.newValue("")
        table.getUndoStack().beginMacro("Cutted Text")
        table.getUndoStack().push(cmd)
        table.getUndoStack().endMacro()

        self.editedSomething()

    def copy(self):
        selectedIndexes = self.model.getCurrentTable().getView().selectionModel().selectedIndexes()
        if len(selectedIndexes) == 0:
            return

        sys_clip = QApplication.clipboard()
        selection = selectedIndexes[0]
        selected_text = str(self.model.getCurrentTable().data(selection))
        sys_clip.setText(selected_text)


    def paste(self):
        table = self.model.getCurrentTable()
        selectedIndexes = self.model.getCurrentTable().getView().selectionModel().selectedIndexes()
        if len(selectedIndexes) == 0:
            return

        sys_clip = QApplication.clipboard()
        value = str(sys_clip.text())
        index = selectedIndexes[0]
        cmd = EditCommand(self.model.getCurrentTable(), index)
        cmd.newValue(value)
        table.getUndoStack().beginMacro("Pasted Text")
        table.getUndoStack().push(cmd)
        table.getUndoStack().endMacro()
        self.editedSomething()

    def editedSomething(self):
        self.model.getCurrentTable().getView().reset()
        self.model.getCurrentTable().setEdited(True)
        self.setUndoRedoMenu()

    def undo(self):
        self.model.getCurrentTable().getUndoStack().undo()
        self.editedSomething()

    def redo(self):
        self.model.getCurrentTable().getUndoStack().redo()
        self.editedSomething()

    def closeWindow(self):
        pass

    def helpWindow(self):
        pass

    def prediction(self,date=None):
        if not date:
            if self.model.getCurrentTable() and self.model.getCurrentTable().getAccessor() and self.model.getCurrentTable().getAccessor().getConnectionType()==ConnectionType.database:
                date = self.model.getCurrentTable().getAccessor().getAccessString()
            else:
                date = self.databaseDialog()
        if date:
            accessor = Accessor(date, ConnectionType.prediction)
            self.generateNewTab(self.handler["databaseHandler"].getPredictionsAsArray(accessor.getAccessString()), accessor)

    def createPrediction(self):
        if self.model.getCurrentTable() and self.model.getCurrentTable().getAccessor() and self.model.getCurrentTable().getAccessor().getConnectionType()==ConnectionType.database:
            date = self.model.getCurrentTable().getAccessor().getAccessString()
        else:
            date = datetime.now().strftime("%Y-%m-%d")
        self.prediction(self.handler["databaseHandler"].createPrediction(date))

    def tabChanged(self):
        self.model.setCurrentIndex(self.form.tabs.currentIndex())

    def closeTab(self, index):
        if not self.model.getTables()[index].isEdited():
            self.removeTab(index)
        else:
            quit_msg = "The file is not saved. Are you sure you want to close the file?"
            reply = QtGui.QMessageBox.question(self, 'Message', quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)

            if reply == QtGui.QMessageBox.Save:
                self.saveResourceThread()
                self.removeTab(index)
            elif reply == QtGui.QMessageBox.Yes:
                self.removeTab(index)

    def removeTab(self, index):
        widget = self.form.tabs.widget(index)
        if widget is not None:
            widget.deleteLater()
        self.form.tabs.removeTab(index)
        self.model.deleteTable(index)


    def setUndoRedoMenu(self):
        undo = "Undo"
        redo = "Redo"
        undoText = self.model.getCurrentTable().getUndoStack().undoText()
        redoText = self.model.getCurrentTable().getUndoStack().redoText()
        if undoText:
            undo+= " (" + undoText + ")"
        if redoText:
            redo+= " (" + redoText + ")"

        self.form.undo.setText(undo)
        self.form.redo.setText(redo)