# ListedSubWindow.py -- Pamhyr
# Copyright (C) 2023-2026  INRAE
#
# This program 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.
#
# This program 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 <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import logging
from functools import reduce

logger = logging.getLogger()


class ListedSubWindow(object):
    def __init__(self, **kwargs):
        super(ListedSubWindow, self).__init__()
        self._sub_win_cnt = 0
        self._sub_win_list = []

    @property
    def sub_win_count(self):
        return self._sub_win_cnt

    @property
    def sub_win_list(self):
        return self._sub_win_list.copy()

    def sub_win_add(self, name, win):
        self._sub_win_list.append((name, win))
        self._sub_win_cnt += 1

        self._update_window_list()

        try:
            logger.debug(
                f"Open window: {name}: {self._sub_win_cnt}")
        except Exception:
            logger.debug(f"Open window: {name}: {self._sub_win_cnt}: X")
            logger.warning(f"Sub window without hash method !")

    def sub_win_del(self, h):
        self._sub_win_list = list(
            filter(
                lambda x: x[1].hash() != h,
                self._sub_win_list
            )
        )
        self._sub_win_cnt = len(self._sub_win_list)
        self._update_window_list()

        logger.debug(f"Close window: ({h}) {self._sub_win_cnt}")

    def _sub_win_exists(self, h):
        res = reduce(
            lambda acc, el: (acc or (h == (el[1].hash()))),
            self._sub_win_list,
            False
        )
        return res

    def sub_win_exists(self, h):
        return self._sub_win_exists(h)

    def get_sub_win(self, h):
        try:
            return next(
                filter(
                    lambda el: (h == el[1].hash()),
                    self._sub_win_list,
                )
            )[1]
        except Exception:
            return None

    def get_sub_window(self, cls, data=None):
        hash = cls._hash(data)
        return self.get_sub_win(hash)

    def sub_window_exists(self, cls, data=None):
        """Check if window already exists

        Check if window already exists, used to deni window open
        duplication

        Args:
            cls: Window class, must inerit to PamhyrWindow or
                PamhyrDialog
            data: Data used for hash computation of cls

        Returns:
            The window if hash already exists on sub window dictionary,
            otherelse None
        """
        hash = cls._hash(data)
        if self._sub_win_exists(hash):
            win = self.get_sub_win(hash)
            logger.debug(f"subwindow: {hash} -> {win} ({win.hash()})")
            win.activateWindow()
            return True
        else:
            return False

    def _update_window_list(self):
        try:
            self._parent._update_window_list()
        except Exception:
            return

    def _close_sub_window(self, exceptions=[]):
        for name, win in self._sub_win_list:
            if name in exceptions:
                continue

            win.close()
