# encoding=utf-8
"""
File for the CotationQuestionsWindow class. This class is an intermediary between Phrase/Texte and CotationWindow
"""

__author__ = "Roland Trouville"
__copyright__ = "Copyright 2015+, Consortium MonPaGe"
__license__ = "Creative Commons 4.0 By-Nc-Sa"
__maintainer__ = "Roland Trouville"
__email__ = "contact.monpage@gmail.com"
__status__ = "Production"

from PySide6.QtCore import Qt
from PySide6.QtWidgets import (
	QCheckBox,
	QGroupBox,
	QLabel,
	QProgressBar,
	QPushButton,
	QRadioButton,
)

from cotation.cotation_window import CotationWindow
from tools.audio_manager import AudioManager
from tools.display_tools import DisplayTools


class CotationQuestionsWindow(CotationWindow):
	"""
	This is the parent for all cotation windows that are absed on the question/answer structure
	"""

	current_file_index = 0

	form = None

	judge_code: str
	session_path: str

	file_list = None

	audio_pbar: QProgressBar
	audio_pbar_label: QLabel

	stimuli = []

	def __init__(
		self,
		parent,
		participant_code,
		module_name,
		judge_code,
		session_path,
		advanced_mode=False,
	):
		super().__init__(participant_code, parent)
		self.module_name = module_name
		self.judge_code = judge_code
		self.session_path = session_path
		self.directory_path = (
			"./data/participant/" + self.participant_code + "/" + session_path
		)
		self.advanced_mode = advanced_mode
		self.stimuli = []

		AudioManager.init()

	def make_questions_group(self, parent, questions, filename, module_name=None):
		"""
		Will generate a GroupBox containing the questions we want to ask for a file in a question type coation module
		:param parent: The parent of the groupbox
		:param questions: array of dict containing the structure of the question (label, possible answers, etc...)
		:param filename: the filename we want to ask the question on
		:param module_name: the module to which the filename and question belong
		:return: the groupbox
		"""
		group = QGroupBox("", parent)
		group_height = 50
		group_width = 410
		question_label_height = 20
		element_width = 90
		cb_txt = "                  "
		if module_name in (
			"ModuleTexte",
			"ModulePneumoPhonatoire",
			"ModuleDiadoco",
			"ModulePhrases"
		):  # moduletexte has longer
			# questions,
			# we need to
			# make them bigger. Plus we
			# display less of them on the same page
			group_height = 50
			question_label_height = 20
			group_width = 750
			element_width = 170
			cb_txt = "                                                      "

		tmp = QPushButton("Ecouter", group)
		tmp.resize(DisplayTools.size(150, 25))
		tmp.move(DisplayTools.coord(10, 15))
		if module_name in ("ModuleTexte", "ModulePneumoPhonatoire", "ModuleDiadoco"):
			tmp.move(DisplayTools.coord(10, 15))
		tmp.setObjectName(filename)
		tmp.clicked.connect(self.listen_to_file)

		audio_pbar = QProgressBar(group)
		audio_pbar.resize(DisplayTools.size(550, 15))
		audio_pbar.move(DisplayTools.coord(170, 20))
		audio_pbar.setTextVisible(False)
		audio_pbar_label = QLabel(group)
		audio_pbar_label.setObjectName("pbar")
		audio_pbar_label.resize(DisplayTools.size(70, 25))
		audio_pbar_label.move(DisplayTools.coord(725, 15))

		questions_to_disable = []

		i = 0
		for quest in questions.values():
			group.setObjectName(str(quest["stimuli_id"]))
			# grp_tmp = QGroupBox(quest["label"], group)
			grp_tmp = QGroupBox("", group)
			grp_tmp.setObjectName(str(quest["question_id"]))

			tmp_lab = QLabel(quest["label"], grp_tmp)
			tmp_lab.setWordWrap(True)
			tmp_lab.move(DisplayTools.coord(5, 2))
			tmp_lab.setAlignment(Qt.AlignmentFlag.AlignTop)
			tmp_lab.resize(DisplayTools.size(group_width - 10, question_label_height))
			if quest["top_question_id"] > 0:
				tmp_lab.resize(
					DisplayTools.size(group_width - 40, question_label_height)
				)

			DisplayTools.set_font_size(tmp_lab, None, True, tmp_lab.font().pointSize())
			if quest["tooltip"] is not None:
				tmp_lab.setToolTip(quest["tooltip"])

			val = self.get_stored_answer(
				self.session_path,
				self.participant_code,
				self.judge_code,
				quest["stimuli_id"],
				quest["question_id"],
			)
			bitval = ""
			if val is not None:
				bitval_base = "{0:0" + str(len(quest["answers"])) + "b}"
				bitval = bitval_base.format(int(val))

			sub_question_id = 0
			if quest["sub_question_id"] is not None:
				sub_question_id = int(quest["sub_question_id"])
				if (
					val == 0 or val is None
				):  # if we have no answer for this question, we need to disable the questions
					#  that consider this question as their parent node
					questions_to_disable.append(sub_question_id)

			for j in range(0, len(quest["answers"])):
				if quest["multichoice"] == 1:
					tmp_rb = QCheckBox(
						cb_txt, grp_tmp
					)  # We put an "empty" label for checkbox so we
				# can "click" on following label and still check this checkbox
				else:
					tmp_rb = QRadioButton(
						cb_txt, grp_tmp
					)  # We put an "empty" label for radiobutton so we
				# can "click" on following label and still check this radiobutton
				tmp_rb.resize(DisplayTools.size(element_width, 15))
				tmp_rb.move(
					DisplayTools.coord(10 + (j * element_width + 5), group_height - 20)
				)
				tmp_rb.setObjectName(
					str(quest["answers"][j][1]) + "_" + str(sub_question_id)
				)
				tmp_rb
				if val is not None:
					if quest["multichoice"] == 1:
						tmp_rb.setChecked(bitval[j] == "1")
					else:
						if val == quest["answers"][j][1]:
							tmp_rb.setChecked(True)

				if sub_question_id > 0:
					tmp_rb.toggled.connect(self.top_question_change)

				tmp_lab = QLabel(quest["answers"][j][2], grp_tmp)
				tmp_lab.setWordWrap(True)
				tmp_lab.move(
					DisplayTools.coord(
						10 + (j * element_width + 5) + 20, group_height - 24
					)
				)
				tmp_lab.setAlignment(Qt.AlignmentFlag.AlignBottom)
				tmp_lab.resize(DisplayTools.size(element_width - 20, 15))
				DisplayTools.set_font_size(
					tmp_lab, None, True, tmp_lab.font().pointSize()
				)

				tmp_rb.raise_()

			grp_tmp.move(DisplayTools.coord(170, 5 + (i * group_height)))
			grp_tmp.resize(DisplayTools.size(group_width, group_height - 5))
			if module_name in (
				"ModuleTexte",
				"ModulePneumoPhonatoire",
				"ModuleDiadoco",
			):
				grp_tmp.move(DisplayTools.coord(10, 45 + (i * group_height)))
				if quest["top_question_id"] > 0:
					grp_tmp.move(DisplayTools.coord(40, 45 + (i * group_height)))
					grp_tmp.resize(
						DisplayTools.size(group_width - 30, group_height - 5)
					)
			i += 1

		for qid in questions_to_disable:
			self.enable_sub_question(qid, False)
		group.resize(DisplayTools.size(group_width, ((group_height + 5) * i)))
		if module_name in ("ModuleTexte", "ModulePneumoPhonatoire", "ModuleDiadoco"):
			group.resize(DisplayTools.size(group_width+20, ((group_height + 5) * i) + 40))
		return group

	def listen_to_file(self):
		"""
		Allows to listen to the audio file that we are asking questions on
		:return:
		"""
		sender = self.sender()
		filename = self.directory_path + str(
			sender.objectName()
		)  # The filename is embeded in the button object name
		AudioManager.stop()
		qbar = sender.parent().findChildren(QProgressBar)[0]
		tmp = sender.parent().findChildren(QLabel)
		qbar_label = None
		for t in tmp:
			if t.objectName() == "pbar":
				qbar_label = t
		AudioManager.play_wave(filename, qbar , qbar_label)

	def save(self):
		"""
		Saving the answers the judge did
		:return:
		"""
		# First we stop the audio in case it was playing when we saved
		AudioManager.stop()

		for gr in self.stimuli:
			stimuli_id = int(str(gr.objectName()))
			questions = gr.findChildren(QGroupBox)
			for ques in questions:
				question_id = int(str(ques.objectName()))
				val = None
				radios = ques.findChildren(QRadioButton)
				if len(radios) > 0:
					for rad in radios:
						if rad.isChecked():
							val = int(str(rad.objectName().split("_")[0]))
				else:  # We have no radio, maybe checkboxes
					val = 0
					checks = ques.findChildren(QCheckBox)
					for i in range(0, len(checks)):
						if checks[i].isChecked():
							val += pow(2, len(checks) - i - 1)

				if val is not None:
					self.set_stored_answer(
						self.session_path,
						self.participant_code,
						self.judge_code,
						stimuli_id,
						question_id,
						str(val),
					)

	def top_question_change(self):
		"""
		Should be abstract
		:return: False
		"""
		return False

	def enable_sub_question(self, qid, enabled):
		"""
		Should be abstract
		:param qid: question id
		:param enabled: enabled or disabled
		:return: False
		"""
		return False
