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

#	Copyright 2011, Milan Boers
#	Copyright 2011-2013, Marten de Vries
#
#	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 os
import weakref
import contextlib

class DummyLesson:
	pass

def installQtClasses():
	global EnterItemListModel, EnterItemList, EnterWidget

	class EnterItemListModel(QtCore.QAbstractListModel):
		"""The model for the list widget with media items (this construction
		   because without model Qt produces a bug)

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

		def update(self,list):
			self.beginResetModel()
			self.listData = [item["name"] for item in list["items"]]
			self.endResetModel()

		def rowCount(self,parent):
			return len(self.listData)

		def data(self,index,role):
			if index.isValid() and role == QtCore.Qt.DisplayRole:
				return self.listData[index.row()]

	class EnterItemList(QtWidgets.QListView):
		"""The list widget with media items"""

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

			self.enterWidget = enterWidget

			self.lm = EnterItemListModel(enterWidget.list,self)
			self.setModel(self.lm)
			self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)

		def update(self):
			self.lm.update(self.enterWidget.list)

		def selectionChanged(self,current,previous):
			self.setRightActiveItem()

		def setRightActiveItem(self):
			if len(self.enterWidget.list["items"]) > 0:
				self.enterWidget.setActiveItem(self.enterWidget.list["items"][self.currentIndex().row()])

	class EnterWidget(QtWidgets.QSplitter):
		"""The enter tab"""

		def __init__(self,*args, **kwargs):
			super().__init__(*args, **kwargs)
			self.list = {
				"items": [],
				"tests": []
			}
			self.lesson = DummyLesson()
			self.activeitem = {
				"id": 0,
				"remote": False,
				"filename": "",
				"name": "",
				"question": "",
				"answer": ""
			}

			self.titlel = QtWidgets.QLabel()
			self.titleTextBox = QtWidgets.QLineEdit()
			self.titleTextBox.textChanged.connect(self.changeTitle)
			leftTop = QtWidgets.QHBoxLayout()
			leftTop.addWidget(self.titlel)
			leftTop.addWidget(self.titleTextBox)

			self.enterItemList = EnterItemList(self)

			self.removeButton = QtWidgets.QPushButton()
			self.removeButton.clicked.connect(self.removeItem)
			self.addLocalButton = QtWidgets.QPushButton()
			self.addLocalButton.clicked.connect(self.addLocalItems)
			self.addRemoteButton = QtWidgets.QPushButton()
			self.addRemoteButton.clicked.connect(self.addRemoteItems)

			leftBottom = QtWidgets.QHBoxLayout()
			leftBottom.addWidget(self.removeButton)
			leftBottom.addWidget(self.addLocalButton)
			leftBottom.addWidget(self.addRemoteButton)

			left = QtWidgets.QVBoxLayout()
			left. addLayout(leftTop)
			left.addWidget(self.enterItemList)
			left.addLayout(leftBottom)
			leftW = QtWidgets.QWidget()
			leftW.setLayout(left)

			self.mediaDisplay = base._modules.default("active", type="mediaDisplay").createDisplay(autoplay=False)

			self.namel = QtWidgets.QLabel()

			self.enterName = QtWidgets.QLineEdit()
			self.enterName.textEdited.connect(self.changeName)
			self.enterName.setEnabled(False)

			self.questionl = QtWidgets.QLabel()

			self.enterQuestion = QtWidgets.QLineEdit()
			self.enterQuestion.textEdited.connect(self.changeQuestion)
			self.enterQuestion.setEnabled(False)

			self.answerl = QtWidgets.QLabel()

			self.enterAnswer = QtWidgets.QLineEdit()
			self.enterAnswer.textEdited.connect(self.changeAnswer)
			self.enterAnswer.setEnabled(False)

			desceditL = QtWidgets.QVBoxLayout()
			desceditL.addWidget(self.namel)
			desceditL.addWidget(self.enterName)
			desceditL.addWidget(self.questionl)
			desceditL.addWidget(self.enterQuestion)
			desceditL.addWidget(self.answerl)
			desceditL.addWidget(self.enterAnswer)

			desceditW = QtWidgets.QWidget()
			desceditW.setLayout(desceditL)

			rightSplitter = QtWidgets.QSplitter(2)
			rightSplitter.addWidget(self.mediaDisplay)
			rightSplitter.addWidget(desceditW)

			right = QtWidgets.QVBoxLayout()
			right.addWidget(rightSplitter)
			rightW = QtWidgets.QWidget()
			rightW.setLayout(right)

			splitter = QtWidgets.QSplitter(self)
			splitter.addWidget(leftW)
			splitter.addWidget(rightW)

			layout = QtWidgets.QHBoxLayout()
			layout.addWidget(splitter)

			self.setLayout(layout)
			self.retranslate()

		def retranslate(self):
			self.titlel.setText(_("Title:"))

			self.removeButton.setText(_("Remove"))
			self.addLocalButton.setText(_("Add local media"))
			self.addRemoteButton.setText(_("Add remote media"))

			self.namel.setText(_("Name:"))
			self.questionl.setText(_("Question:"))
			self.answerl.setText(_("Answer:"))

		def addLocalItems(self):
			"""Add items from the local disk to the list"""

			extensions = []
			for module in base._modules.sort("active", type="mediaType"):
				with contextlib.suppress(AttributeError):
					#AttributeError: no extensions
					extensions.extend(module.extensions)

			extensionsStr = "("
			for extension in extensions:
				extensionsStr += "*" + extension + " "
			extensionsStr += ")"

			filenames = QtWidgets.QFileDialog.getOpenFileNames(
				self,
				_(_("Select file(s)")),
				QtCore.QDir.homePath(),
				_("Media") + " " + extensionsStr
			)[0]
			for filename in filenames:
				self.addItem(filename, remote=False)

		def addRemoteItems(self):
			"""Add items from the internet to the list"""

			sitenames = []
			for module in base._modules.sort("active", type="mediaType"):
				with contextlib.suppress(AttributeError):
					#AttributeError: No name
					sitenames.extend(module.remoteNames)

			sitenamesStr = ""
			for sitename in sitenames:
				sitenamesStr += sitename + ", "
			sitenamesStr = sitenamesStr[:-2]

			url, dialog = QtWidgets.QInputDialog.getText(
				self,
				_("File URL"),
				_("Enter the URL of your website or media item.\nSupported video sites: ") + sitenamesStr + "."
			)
			if dialog:
				self.addItem(url, remote=True)

		def updateWidgets(self):
			"""Updates all the widgets if the list has changed"""

			self.enterItemList.update()
			self.titleTextBox.setText(self.list.get("title", u""))
			self.setActiveItem(self.activeitem)

		def addItem(self,filename,remote=False,name=None,question=None,answer=None):
			"""Add an item to the list"""

			# Check if file is supported
			for module in base._modules.sort("active", type="mediaType"):
				if module.supports(filename):
					item = {
						"id": 0,
						"remote": remote,
						"filename": filename,
						"name": name,
						"question": "",
						"answer": ""
					}
					# Set id
					try:
						item["id"] = self.list["items"][-1]["id"] +1
					except IndexError:
						item["id"] = 0

					if name:
						item["name"] = name
					else:
						if remote == False:
							item["name"] = os.path.basename(filename)
						else:
							item["name"] = filename
					if question:
						item["question"] = question
					if answer:
						item["answer"] = answer

					self.list["items"].append(item)
					self.lesson.changed = True
					self.updateWidgets()
					break
			else:
				QtWidgets.QMessageBox.critical(
					self,
					_("Unsupported file type"),
					_("This type of file is not supported:\n") + filename
				)

		def removeItem(self):
			"""Remove an item from the list"""

			if self.activeitem in self.list["items"]:
				self.list["items"].remove(self.activeitem)
				self.updateWidgets()
				self.mediaDisplay.clear()
				self.enterName.setText("")
				self.enterName.setEnabled(False)
				self.enterQuestion.setText("")
				self.enterQuestion.setEnabled(False)
				self.enterAnswer.setText("")
				self.enterAnswer.setEnabled(False)
				self.enterItemList.setRightActiveItem()

		def setActiveItem(self,item):
			"""Change the active item"""

			self.enterName.setEnabled(True)
			self.enterName.setText(item["name"])
			self.enterQuestion.setEnabled(True)
			self.enterQuestion.setText(item["question"])
			self.enterAnswer.setEnabled(True)
			self.enterAnswer.setText(item["answer"])
			if item["filename"] != self.activeitem["filename"]:
				self.mediaDisplay.showMedia(item["filename"], item["remote"], False)
			self.activeitem = item

		def changeTitle(self, text):
			"""Change the title of the media list"""

			if self.list.get("title", u"") != text:
				self.list["title"] = text
				self.lesson.changed = True

		def changeName(self):
			"""Change the name of the active item"""

			if self.activeitem["name"] != self.enterName.text():
				self.activeitem["name"] = self.enterName.text()
				self.updateWidgets()
				self.lesson.changed = True

		def changeQuestion(self):
			"""Change the question of the active item"""

			if self.activeitem["question"] != self.enterQuestion.text():
				self.activeitem["question"] = self.enterQuestion.text()
				self.lesson.changed = True

		def changeAnswer(self):
			"""Change the description of the active item"""

			if self.activeitem["answer"] != self.enterAnswer.text():
				self.activeitem["answer"] = self.enterAnswer.text()
				self.lesson.changed = True

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

		global base
		base = self

		self._mm = moduleManager

		self.type = "mediaEnterer"
		self.priorities = {
			"default": 510,
		}

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

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

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

		self._widgets = set()

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

		self.active = True

	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._widgets:
			widget = ref()
			if widget is not None:
				widget.retranslate()

	def disable(self):
		self.active = False

		del self._modules
		del self._widgets

	def createMediaEnterer(self):
		ew = EnterWidget()
		self._widgets.add(weakref.ref(ew))
		return ew

def init(moduleManager):
	return MediaEntererModule(moduleManager)
