# This is a sample Python script.
import asyncio
import sys
from PyQt5 import QtGui, QtWidgets, QtCore
from ws.client.ws_client import WsClient
from ws.connection import IConnection
import json
from queue import Queue


class Window(QtWidgets.QMainWindow, IConnection):

	# Use signals and slots to avoid crashes
	# during updating gui elements from websocket context
	upd_progressbar_signal = QtCore.pyqtSignal(int, int)
	upd_color_signal = QtCore.pyqtSignal(str)

	def __init__(self):
		QtWidgets.QMainWindow.__init__(self)
		self.ws_client = WsClient(self)
		self.is_exit_gracefully = True
		self.textEdit = None
		self.progressbar = []
		self.styleChoice = None

		self.setGeometry(50, 50, 500, 300)
		self.setWindowTitle("Hallo Mausi!")
		self.setWindowIcon(QtGui.QIcon('res/flasche.png'))

		self.menubar_create()
		self.statusbar_create()
		self.toolbar_create()
		self.buttons_create()
		self.checkbox_create()

		self.progressbar_create()
		self.style_chooser_create()
		self.calendar_create()

		self.send_data = Queue()
		self.show()

		self.upd_progressbar_signal.connect(self.upd_progressbar_slot)
		self.upd_color_signal.connect(self.upd_color_slot)

	def calendar_create(self):
		cal = QtWidgets.QCalendarWidget(self)
		cal.move(500, 200)
		cal.resize(250, 250)

	def menubar_create(self):
		mainMenu = self.menuBar()
		fileMenu = mainMenu.addMenu("&File")

		actionExit = QtWidgets.QAction("&Exit", self)
		actionExit.setShortcut("Ctrl+Q")
		actionExit.setStatusTip("Leave the App")
		actionExit.triggered.connect(self.on_btn_exit_clicked)

		actionEditor = QtWidgets.QAction("&Editor", self)
		actionEditor.setShortcut("Ctrl+E")
		actionEditor.setStatusTip("Open Editor")
		actionEditor.triggered.connect(self.on_action_editor)

		actionFileOpener = QtWidgets.QAction("File &Open", self)
		actionFileOpener.setShortcut("Ctrl+O")
		actionFileOpener.setStatusTip("Open a file")
		actionFileOpener.triggered.connect(self.on_action_file_open)

		actionFileSaver = QtWidgets.QAction("File &Save", self)
		actionFileSaver.setShortcut("Ctrl+S")
		actionFileSaver.setStatusTip("Save a file")
		actionFileSaver.triggered.connect(self.on_action_file_save)

		fileMenu.addAction(actionExit)
		fileMenu.addAction(actionEditor)
		fileMenu.addAction(actionFileOpener)
		fileMenu.addAction(actionFileSaver)

	def statusbar_create(self):
		statusBar = self.statusBar()

	def toolbar_create(self):
		def action_caller(a, n):
			return lambda action: self.on_action_triggered(a, n)

		action1 = QtWidgets.QAction(QtGui.QIcon('res/glass.png'), "Drink a beer!", self)
		action1.triggered.connect(action_caller(action1, 1))

		action2 = QtWidgets.QAction(QtGui.QIcon('res/glass2.png'), "Drink more beer!", self)
		action2.triggered.connect(action_caller(action2, 2))

		action3 = QtWidgets.QAction(QtGui.QIcon('res/glass_flasche.png'), "Choose font!", self)
		action3.triggered.connect(self.on_action_font_triggered)

		action4 = QtWidgets.QAction(QtGui.QIcon('res/dose.png'), "Choose color!", self)
		action4.triggered.connect(self.on_action_color_triggered)

		toolbar = self.addToolBar("Toolbar")

		toolbar.addAction(action1)
		toolbar.addAction(action2)
		toolbar.addAction(action3)
		toolbar.addAction(action4)

	def buttons_create(self):
		btn = QtWidgets.QPushButton("Quit", self)
		btn.clicked.connect(self.on_btn_exit_clicked)
		btn.resize(btn.minimumSizeHint())
		btn.move(0, 100)

	def checkbox_create(self):
		checkbox = QtWidgets.QCheckBox('Exit gracefully!', self)
		checkbox.stateChanged.connect(self.on_checkbox_changed)
		checkbox.setCheckState(2 if self.is_exit_gracefully else 0)
		checkbox.move(0, 150)

	def progressbar_create(self):
		for i in range(0, 3):
			progressbar = QtWidgets.QProgressBar(self)
			progressbar.setGeometry(200, 80+25*i, 250, 20)
			self.progressbar.append(progressbar)

		btn = QtWidgets.QPushButton("Download", self)
		btn.clicked.connect(self.on_btn_download_clicked)
		btn.move(0, 70)

	def style_chooser_create(self):
		print(self.style().objectName())
		self.styleChoice = QtWidgets.QLabel("Linux", self)
		comboxBox = QtWidgets.QComboBox(self)
		comboxBox.addItem("motif")
		comboxBox.addItem("Windows")
		comboxBox.addItem("cde")
		comboxBox.addItem("Plastique")
		comboxBox.addItem("Cleanlooks")
		comboxBox.addItem("windowsvista")
		comboxBox.addItem("fusion")
		comboxBox.move(50, 250)
		self.styleChoice.move(150, 150)
		comboxBox.activated[str].connect(self.on_combobox_changed)

	def on_btn_exit_clicked(self):
		print('PyQt5 on_btn_click')
		self.close()

	def on_action_triggered(self, action, n):
		print('PyQt5 on_action_triggered {}'.format(n))
		if n == 1:
			self.ws_client.connect(uri="ws://localhost:8765")
		if n == 2:
			self.ws_client.disconnect()

	def on_action_editor(self):
		self.textEdit = QtWidgets.QTextEdit()
		self.setCentralWidget(self.textEdit)

	def on_action_file_open(self):
		name, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open file')
		file = open(name, 'r')

		self.on_action_editor()
		with file:
			text = file.read()
			self.textEdit.setText(text)

	def on_action_file_save(self):

		if self.textEdit is not None:
			name, _ = QtWidgets.QFileDialog.getSaveFileName(self, 'Save file')
			file = open(name, 'w')
			text = self.textEdit.toPlainText()
			file.write(text)
			file.close()
		else:
			print("No file to save!")

	def on_action_font_triggered(self):
		font, valid = QtWidgets.QFontDialog.getFont()
		if valid:
			self.styleChoice.setFont(font)

	def on_action_color_triggered(self):
		color = QtWidgets.QColorDialog.getColor()
		self.send_data.put({'Color': color.name()})

	def on_checkbox_changed(self, state):
		print('PyQt5 on_checkbox_changed, state={}'.format(state))
		if state == QtCore.Qt.Checked:
			self.is_exit_gracefully = True
		else:
			self.is_exit_gracefully = False

	def on_btn_download_clicked(self):
		print("Nothing happens!")

	def on_combobox_changed(self, text):
		self.styleChoice.setText(text)
		QtWidgets.QApplication.setStyle(QtWidgets.QStyleFactory.create(text))

	def on_connect(self):
		self.send_data.put_nowait({'+':'a'})
		self.send_data.put_nowait({'+':'b'})
		self.send_data.put_nowait({'+':'c'})
		self.send_data.put_nowait({'+':'Color'})

	def on_disconnect(self):
		pass

	@QtCore.pyqtSlot(int, int)
	def upd_progressbar_slot(self, n, v):
		self.progressbar[n].setValue(v)

	@QtCore.pyqtSlot(str)
	def upd_color_slot(self, color_str):
		self.styleChoice.setStyleSheet("QWidget {background-color: %s}" % color_str)

	async def on_recv(self, data):
		try:
			d = json.loads(data)
			keys = {'a': 0, 'b': 1, 'c': 2}
			color = {'Color': 0}
			for cmd in d:
				if cmd in keys.keys():
					await asyncio.get_event_loop().run_in_executor(None, self.upd_progressbar_signal.emit(keys[cmd], int(d[cmd] + 0.5)))

				if cmd in color.keys():
					await asyncio.get_event_loop().run_in_executor(None, self.upd_color_signal.emit(d[cmd]))
		except:
			pass

	async def on_send(self):
		try:
			data = await asyncio.get_event_loop().run_in_executor(None, self.send_data.get, True, 1)
			return data
		except:
			return None

	def closeEvent(self, event):
		if self.is_exit_gracefully:
			print("Exitting gracefully!")
			self.ws_client.disconnect()


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

	gui = Window()
	sys.exit(app.exec_())

# See PyCharm help at https://www.jetbrains.com/help/pycharm/
