#!/usr/bin/env python3

"""
BORIS
Behavioral Observation Research Interactive Software
Copyright 2012-2020 Olivier Friard

This file is part of BORIS.

  BORIS 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
  any later version.

  BORIS 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 this program; if not see <http://www.gnu.org/licenses/>.

"""


import logging
import os
import sys

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDialog

from boris import duration_widget
from boris.config import *
from boris.param_panel_ui import Ui_Dialog


class Param_panel(QDialog, Ui_Dialog):

    def __init__(self, parent=None):

        super().__init__()
        self.setupUi(self)


        # insert duration widget for time offset
        self.start_time = duration_widget.Duration_widget(0)
        self.horizontalLayout.insertWidget(1, self.start_time)
        self.end_time = duration_widget.Duration_widget(0)
        self.horizontalLayout_6.insertWidget(1, self.end_time)


        self.pbSelectAllSubjects.clicked.connect(lambda: self.subjects_button_clicked("select all"))
        self.pbUnselectAllSubjects.clicked.connect(lambda: self.subjects_button_clicked("unselect all"))
        self.pbReverseSubjectsSelection.clicked.connect(lambda: self.subjects_button_clicked("reverse selection"))

        self.pbSelectAllBehaviors.clicked.connect(lambda: self.behaviors_button_clicked("select all"))
        self.pbUnselectAllBehaviors.clicked.connect(lambda: self.behaviors_button_clicked("unselect all"))
        self.pbReverseBehaviorsSelection.clicked.connect(lambda: self.behaviors_button_clicked("reverse selection"))

        self.pbOK.clicked.connect(self.ok)
        self.pbCancel.clicked.connect(self.reject)

        self.lwBehaviors.itemClicked.connect(self.behavior_item_clicked)

        self.rb_full.clicked.connect(lambda: self.rb_time(TIME_FULL_OBS))
        self.rb_limit.clicked.connect(lambda: self.rb_time(TIME_EVENTS))
        self.rb_interval.clicked.connect(lambda: self.rb_time(TIME_ARBITRARY_INTERVAL))


    def rb_time(self, button):
        """
        time
        """
        self.frm_time_interval.setEnabled(button == TIME_ARBITRARY_INTERVAL)


    def subjects_button_clicked(self, command):
        for idx in range(self.lwSubjects.count()):
            cb = self.lwSubjects.itemWidget(self.lwSubjects.item(idx))
            if command == "select all":
                cb.setChecked(True)
            if command == "unselect all":
                cb.setChecked(False)
            if command == "reverse selection":
                cb.setChecked(not cb.isChecked())


    def behaviors_button_clicked(self, command):
        for idx in range(self.lwBehaviors.count()):

            if self.lwBehaviors.item(idx).data(33) != "category":
                if command == "select all":
                    self.lwBehaviors.item(idx).setCheckState(Qt.Checked)

                if command == "unselect all":
                    self.lwBehaviors.item(idx).setCheckState(Qt.Unchecked)

                if command == "reverse selection":
                    if self.lwBehaviors.item(idx).checkState() == Qt.Checked:
                        self.lwBehaviors.item(idx).setCheckState(Qt.Unchecked)
                    else:
                        self.lwBehaviors.item(idx).setCheckState(Qt.Checked)


    def ok(self):

        selectedSubjects = []
        for idx in range(self.lwSubjects.count()):
            cb = self.lwSubjects.itemWidget(self.lwSubjects.item(idx))
            if cb.isChecked():
                selectedSubjects.append(cb.text())
        self.selectedSubjects = selectedSubjects

        selectedBehaviors = []
        for idx in range(self.lwBehaviors.count()):
            if self.lwBehaviors.item(idx).checkState() == Qt.Checked:
                selectedBehaviors.append(self.lwBehaviors.item(idx).text())
        self.selectedBehaviors = selectedBehaviors

        self.accept()


    def behavior_item_clicked(self, item):
        """
        check / uncheck behaviors belonging to the clicked category
        """

        if item.data(33) == "category":
            category = item.data(34)
            for i in range(self.lwBehaviors.count()):
                if self.lwBehaviors.item(i).data(34) == category and self.lwBehaviors.item(i).data(33) != "category":

                    if item.data(35):
                        self.lwBehaviors.item(i).setCheckState(Qt.Unchecked)
                    else:
                        self.lwBehaviors.item(i).setCheckState(Qt.Checked)

            item.setData(35, not item.data(35))


    def extract_observed_behaviors(self, selected_observations, selected_subjects):
        """
        extract unique behaviors codes from obs_id observation and selected subjects
        """

        observed_behaviors = []

        # extract events from selected observations
        all_events = [self.pj[OBSERVATIONS][x][EVENTS] for x in self.pj[OBSERVATIONS] if x in selected_observations]

        for events in all_events:
            for event in events:
                if (event[EVENT_SUBJECT_FIELD_IDX] in selected_subjects
                        or (not event[EVENT_SUBJECT_FIELD_IDX] and NO_FOCAL_SUBJECT in selected_subjects)):
                    observed_behaviors.append(event[EVENT_BEHAVIOR_FIELD_IDX])

        # remove duplicate
        return list(set(observed_behaviors))


    def cb_changed(self):
        selectedSubjects = []
        for idx in range(self.lwSubjects.count()):
            cb = self.lwSubjects.itemWidget(self.lwSubjects.item(idx))
            if cb and cb.isChecked():
                selectedSubjects.append(cb.text())

        # FIX ME
        observedBehaviors = self.extract_observed_behaviors(self.selectedObservations, selectedSubjects)

        logging.debug(f"observed behaviors: {observedBehaviors}")

        for idx in range(self.lwBehaviors.count()):

            if self.lwBehaviors.item(idx).data(33) != "category":
                if self.lwBehaviors.item(idx).text() in observedBehaviors:
                    self.lwBehaviors.item(idx).setCheckState(Qt.Checked)
                else:
                    self.lwBehaviors.item(idx).setCheckState(Qt.Unchecked)