#! /usr/bin/env python3
# -*- coding: utf-8 -*-

#	Copyright 2009-2012, 2014, Marten de Vries
#	Copyright 2008-2011, Milan Boers
#
#	This file is part of OpenTeacher.
#
#	OpenTeacher is free software: you can redistribute it and/or modify
#	it under the terms of the GNU General Public License as published by
#	the Free Software Foundation, either version 3 of the License, or
#	(at your option) any later version.
#
#	OpenTeacher is distributed in the hope that it will be useful,
#	but WITHOUT ANY WARRANTY; without even the implied warranty of
#	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#	GNU General Public License for more details.
#
#	You should have received a copy of the GNU General Public License
#	along with OpenTeacher.  If not, see <http://www.gnu.org/licenses/>.

import weakref

def installQtClasses():
	global CharsKeyboardWidget, KeyboardsWidget

	class CharsKeyboardWidget(QtWidgets.QWidget):
		"""A keyboard widget that displays all characters passed to it
		   in the constructor, and emits the letterChosen signal when
		   one is clicked.

		"""
		letterChosen = QtCore.pyqtSignal([object])

		def __init__(self, characters, *args,  **kwargs):
			super().__init__(*args, **kwargs)

			topWidget = QtWidgets.QWidget()

			layout = QtWidgets.QGridLayout()
			layout.setSpacing(1)
			layout.setContentsMargins(0, 0, 0, 0)

			i = 0
			for line in characters:
				j = 0
				for item in line:
					b = QtWidgets.QPushButton(item)
					b.clicked.connect(self._letterChosen)
					b.setMinimumSize(1, 1)
					b.setFlat(True)
					b.setAutoFillBackground(True)
					palette = b.palette()
					if i % 2 == 0:
						brush = palette.brush(QtGui.QPalette.Base)
					else:
						brush = palette.brush(QtGui.QPalette.AlternateBase)
					palette.setBrush(QtGui.QPalette.Button, brush)
					b.setPalette(palette)
					if not item:
						b.setEnabled(False)
					layout.addWidget(b, i, j)
					j += 1
				i+= 1
			topWidget.setLayout(layout)
			palette = topWidget.palette()
			brush = palette.brush(QtGui.QPalette.WindowText)
			palette.setBrush(QtGui.QPalette.Window, QtCore.Qt.darkGray)
			topWidget.setPalette(palette)
			topWidget.setAutoFillBackground(True)

			mainLayout = QtWidgets.QVBoxLayout()
			mainLayout.addWidget(topWidget)
			mainLayout.addStretch()
			mainLayout.setContentsMargins(0, 0, 0, 0)
			self.setLayout(mainLayout)

			topWidget.setSizePolicy(
				QtWidgets.QSizePolicy.Expanding,
				QtWidgets.QSizePolicy.Maximum
			)

		def _letterChosen(self):
			text = self.sender().text()
			self.letterChosen.emit(text)

	class KeyboardsWidget(QtWidgets.QTabWidget):
		"""A container of keyboard widgets, it has one keyboard widget
		   for every different table of characters.

		"""
		def __init__(self, createEvent, data, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self.letterChosen = createEvent()
			self._data = data
			self.update()

		def update(self):
			#clean the widget, needed if this method has been called before.
			self.clear()
			for module in self._data:
				#create tab and add it to the widget
				tab = CharsKeyboardWidget(module.data)
				self.addTab(tab, module.name)
				#connect the event that handles letter selection
				tab.letterChosen.connect(self.letterChosen.send)

class CharsKeyboardModule:
	"""This module offers an onscreen character keyboard widget, which
	   makes use of the char modules as its data source.

	"""
	def __init__(self, moduleManager, *args, **kwargs):
		super().__init__(*args, **kwargs)

		self._mm = moduleManager
		self.type = "charsKeyboard"
		self.requires = (
			self._mm.mods(type="ui"),
			self._mm.mods(type="event"),
			self._mm.mods(type="chars"),
			self._mm.mods(type="translator"),
		)

	def enable(self):
		global QtCore, QtGui, QtWidgets
		try:
			from PyQt5 import QtCore, QtGui, QtWidgets
		except ImportError:
			return
		installQtClasses()

		self._modules = set(self._mm.mods(type="modules")).pop()
		self._widgets = set()

		try:
			translator = self._modules.default("active", type="translator")
		except IndexError:
			pass
		else:
			translator.languageChangeDone.handle(self._update)

		#to make sure the widgets are updated when their data sources
		#are updated.
		for dataMod in self._mm.mods("active", type="chars"):
			if hasattr(dataMod, "updated"):
				dataMod.updated.handle(self._update)

		self.active = True

	def disable(self):
		self.active = False

		del self._modules
		del self._widgets

	def createWidget(self):
		"""Creates a keyboard widget. It has one OT-style event:
		   letterChosen. Handlers should add the as argument passed char
		   to their input box.

		"""
		kw = KeyboardsWidget(
			self._modules.default(type="event").createEvent,
			self._modules.sort("active", type="chars")
		)
		self._widgets.add(weakref.ref(kw))
		return kw

	def _update(self):
		for ref in self._widgets:
			widget = ref()
			if widget is not None:
				widget.update()

def init(moduleManager):
	return CharsKeyboardModule(moduleManager)
