class E90Dashboard(QMainWindow):
    WINDOW_WIDTH = 400
    WINDOW_HEIGHT = 300

    def __init__(self, parent=None):
        super().__init__(parent)
        self.dashboard = Dashboard()
        self.createUi()

        self.dashboardUpdateTimer = QTimer(self)
        self.dashboardUpdateTimer.setInterval(5)
        self.dashboardUpdateTimer.timeout.connect(self.updateDashboard)

    def createUi(self):
        #
        # Main window
        #
        self.resize(self.WINDOW_WIDTH, self.WINDOW_HEIGHT)
        self.setWindowTitle("E90 Dashboard")
        self.setMaximumSize(self.WINDOW_WIDTH, self.WINDOW_HEIGHT)
        self.setMinimumSize(self.WINDOW_WIDTH, self.WINDOW_HEIGHT)

        self.widget = QWidget(self)
        self.setCentralWidget(self.widget)

        #
        # Layouts
        #
        self.mainlayout = QVBoxLayout(self)

        #
        # Dashboard
        #
        self.serialGroupBox = SerialGroupBox(self)
        self.serialGroupBox.connectButton.pressed.connect(
            self.onConnectButtonPress)
        self.mainlayout.addWidget(self.serialGroupBox)

        #
        # Game
        #
        self.gameGroupBox = GameGroupBox(self)
        self.mainlayout.addWidget(self.gameGroupBox)

        #
        # Apply
        #
        self.widget.setLayout(self.mainlayout)

    def onConnectButtonPress(self):
        if (self.serialGroupBox.port
                is not None) and (not self.dashboard.isOpen()):
            self.connect()
        else:
            self.disconnect()
        pass

    def connect(self):
        self.dashboard.open(self.serialGroupBox.port.device)
        self.serialGroupBox.connectButton.setText("Disconnect")
        self.dashboardUpdateTimer.start()
        self.serialGroupBox.lock()

    def disconnect(self):
        self.dashboard.close()
        self.serialGroupBox.connectButton.setText("Connect")
        self.dashboardUpdateTimer.stop()
        self.serialGroupBox.unlock()

    def updateDashboard(self):
        if self.dashboard.isOpen():
            try:
                self.dashboard.update()
            except serial.serialutil.SerialTimeoutException as e:
                QMessageBox.critical(self, "Error", "Dashboard: " + str(e))
                self.disconnect()