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

#	Copyright 2011-2013, Marten de Vries
#	Copyright 2008-2011, Roel Huybrechts
#
#	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/>.

#pyratemp, QtCore & QtWidgets imported in enable()
import random
import weakref

def installQtClasses():
	global AboutDialog

	class AboutTextLabel(QtWidgets.QLabel):
		def __init__(self, metadata, templatePath, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self._metadata = metadata
			self._templatePath = templatePath

			self.setOpenExternalLinks(True)
			self.setAlignment(QtCore.Qt.AlignCenter)

		def retranslate(self):
			with open(self._templatePath, encoding='UTF-8') as f:
				t = pyratemp.Template(f.read())
			data = self._metadata.copy()
			data.update({
				"websiteText": _("Project website"),
			})
			self.setText(t(**data))

	class AboutImageLabel(QtWidgets.QLabel):
		def __init__(self, metadata, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self.setPixmap(QtGui.QPixmap(metadata["comicPath"]))
			self.setAlignment(QtCore.Qt.AlignCenter)

	class AboutWidget(QtWidgets.QWidget):
		"""The about page (shows some metadata)."""

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

			imageLabel = AboutImageLabel(metadata)
			self.textLabel = AboutTextLabel(metadata, templatePath)

			layout = QtWidgets.QVBoxLayout()
			layout.addStretch()
			layout.addWidget(imageLabel)
			layout.addStretch()
			layout.addWidget(self.textLabel)
			layout.addStretch()
			self.setLayout(layout)

		def retranslate(self):
			self.textLabel.retranslate()

	class ShortLicenseWidget(QtWidgets.QWidget):
		def __init__(self, metadata, *args, **kwargs):
			super().__init__(*args, **kwargs)

			label = QtWidgets.QLabel()
			label.setText(metadata["licenseIntro"])
			self.fullLicenseButton = QtWidgets.QPushButton()

			vbox = QtWidgets.QVBoxLayout()
			vbox.addWidget(label)
			vbox.addWidget(self.fullLicenseButton)

			self.layout = QtWidgets.QHBoxLayout()
			self.layout.addStretch()
			self.layout.addLayout(vbox)
			self.layout.addStretch()
			self.setLayout(self.layout)

		def retranslate(self):
			self.fullLicenseButton.setText(_("Full license text"))

	class LongLicenseWidget(QtWidgets.QTextEdit):
		def __init__(self, metadata, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self.setReadOnly(True)
			self.setText(metadata["license"])

	class LicenseWidget(QtWidgets.QStackedWidget):
		"""The license page. Can show both the short copyright notice,
		   and the full license.

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

			self.shortLicenseWidget = ShortLicenseWidget(metadata)
			self.longLicenseWidget = LongLicenseWidget(metadata)

			self.shortLicenseWidget.fullLicenseButton.clicked.connect(self.showFullLicense)

			self.addWidget(self.shortLicenseWidget)
			self.addWidget(self.longLicenseWidget)

		def retranslate(self):
			self.shortLicenseWidget.retranslate()

		def showFullLicense(self):
			self.setCurrentIndex(1) #longLicenseWidget

	class PersonWidget(QtWidgets.QWidget):
		def __init__(self, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self.taskLabel = QtWidgets.QLabel("")
			self.taskLabel.setStyleSheet("font-size:24pt;")
			self.nameLabel = QtWidgets.QLabel("")
			self.nameLabel.setStyleSheet("font-size:36pt;")

			#to prevent flash of unstyled content
			palette = QtGui.QPalette()
			color = palette.windowText().color()
			color.setAlpha(0)
			palette.setColor(QtGui.QPalette.WindowText, color)

			self.taskLabel.setPalette(palette)
			self.nameLabel.setPalette(palette)

			self.taskLabel.setAlignment(QtCore.Qt.AlignCenter)
			self.nameLabel.setAlignment(QtCore.Qt.AlignCenter)

			self.layout = QtWidgets.QVBoxLayout()
			self.layout.addWidget(self.taskLabel)
			self.layout.addStretch()
			self.layout.addWidget(self.nameLabel)
			self.setLayout(self.layout)

		def update(self, task, name):
			self.taskLabel.setText(task)
			self.nameLabel.setText(name)

		def fade(self, step):
			if step <= 255:
				alpha = step
			elif step > 765:
				alpha = 1020 - step
			else:
				return

			palette = QtGui.QPalette()
			color = palette.windowText().color()
			color.setAlpha(alpha)
			palette.setColor(QtGui.QPalette.WindowText, color)

			self.taskLabel.setPalette(palette)
			self.nameLabel.setPalette(palette)

	class AuthorsWidget(QtWidgets.QWidget):
		"""The authors widget. Displays all authors of OpenTeacher with
		   a fade animation.

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

			if len(authors) == 0:
				self.authors = None
			else:
				self.backupAuthors = list(authors)
				self.authors = []

			self.personWidget = PersonWidget()
			self.launchpadLabel = QtWidgets.QLabel()
			self.launchpadLabel.setAlignment(QtCore.Qt.AlignCenter)

			self.layout = QtWidgets.QVBoxLayout()
			self.layout.addWidget(self.personWidget)
			self.layout.addStretch()
			self.layout.addWidget(self.launchpadLabel)
			self.setLayout(self.layout)

			self.animationActive = False

		def retranslate(self):
			self.launchpadLabel.setText(
				_("Thanks to all Launchpad contributors!")
			)

		def startAnimation(self):
			self.nextAuthor()
			timeLine = QtCore.QTimeLine(5000, self)
			#4x 255; 2x for the alpha gradients, 2x for a pause
			timeLine.setFrameRange(0, 1020)
			timeLine.frameChanged.connect(self.personWidget.fade)
			timeLine.finished.connect(self.startAnimation)
			timeLine.start()
			self.animationActive = True

		def nextAuthor(self):
			if self.authors is None:
				return
			try:
				self.personWidget.update(*self.authors.pop())
			except IndexError:
				self.authors = self.backupAuthors[:]
				random.shuffle(self.authors)
				self.nextAuthor()

	class AboutDialog(QtWidgets.QTabWidget):
		"""The about dialog, consists of an about page, a license page
		   and an authors page.

		"""
		def __init__(self, authors, metadata, templatePath, *args, **kwargs):
			super().__init__(*args, **kwargs)

			self.setTabPosition(QtWidgets.QTabWidget.South)
			self.setDocumentMode(True)

			self.aboutWidget = AboutWidget(metadata, templatePath)
			self.licenseWidget = LicenseWidget(metadata)
			self.authorsWidget = AuthorsWidget(authors)

			self.addTab(self.aboutWidget, "")
			self.addTab(self.licenseWidget, "")
			self.addTab(self.authorsWidget, "")

			self.currentChanged.connect(self.startAnimation)

		def retranslate(self):
			self.setWindowTitle(_("About"))
			self.setTabText(0, _("About"))
			self.setTabText(1, _("License"))
			self.setTabText(2, _("Authors"))

			self.aboutWidget.retranslate()
			self.licenseWidget.retranslate()
			self.authorsWidget.retranslate()

		def startAnimation(self):
			if self.currentWidget() == self.authorsWidget and not self.authorsWidget.animationActive:
				self.authorsWidget.startAnimation()

class AboutDialogModule:
	"""Provides the about dialog."""

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

		self._mm = moduleManager
		self.type = "about"

		self.requires = (
			self._mm.mods(type="ui"),
		)
		self.uses = (
			self._mm.mods(type="translator"),
			self._mm.mods(type="authors"),
		)
		self.filesWithTranslations = ("about.py",)

	def show(self):
		try:
			module = self._modules.default("active", type="authors")
		except IndexError:
			authors = set()
		else:
			authors = module.registeredAuthors
		metadata = self._modules.default("active", type="metadata").metadata
		templatePath = self._mm.resourcePath("about.html")
		dialog = AboutDialog(authors, metadata, templatePath)
		self._activeDialogs.add(weakref.ref(dialog))

		tab = self._modules.default("active", type="ui").addCustomTab(dialog)
		dialog.tab = tab
		tab.closeRequested.handle(tab.close)

		self._retranslate()

	def _retranslate(self):
		global _
		global ngettext

		try:
			translator = self._modules.default("active", type="translator")
		except IndexError:
			_, ngettext = str, lambda a, b, n: a if n == 1 else b
		else:
			_, ngettext = translator.gettextFunctions(
				self._mm.resourcePath("translations")
			)
		for ref in self._activeDialogs:
			dialog = ref()
			if dialog is not None:
				dialog.retranslate()
				dialog.tab.title = dialog.windowTitle()

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

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

		#load translator
		try:
			translator = self._modules.default("active", type="translator")
		except IndexError:
			pass
		else:
			translator.languageChanged.handle(self._retranslate)
		self._retranslate()

		self.active = True

	def disable(self):
		self.active = False

		del self._modules
		del self._activeDialogs

def init(moduleManager):
	return AboutDialogModule(moduleManager)
