#!/usr/bin/env python3
"""
Módulo de Gerenciamento de Tela Cheia do FastChecker II

Responsável por:
- Suporte a F11 para tela cheia em todos os módulos
- Suporte a múltiplos monitores no Windows 7
- Detecção automática de monitores
- Gerenciamento de resoluções
"""

import sys
import os
from typing import List, Tuple, Optional
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QKeyEvent, QScreen
import logging

# Configurar logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


class MonitorInfo:
    """Informações sobre um monitor"""
    
    def __init__(self, screen: QScreen):
        self.screen = screen
        self.name = screen.name()
        self.geometry = screen.geometry()
        self.available_geometry = screen.availableGeometry()
        self.size = screen.size()
        self.physical_size = screen.physicalSize()
        self.logical_dots_per_inch = screen.logicalDotsPerInch()
        self.device_pixel_ratio = screen.devicePixelRatio()
    
    def __str__(self):
        return (f"Monitor: {self.name}, "
                f"Resolução: {self.size.width()}x{self.size.height()}, "
                f"Posição: ({self.geometry.x()}, {self.geometry.y()})")


class FullscreenManager:
    """
    Gerenciador de tela cheia e múltiplos monitores
    
    Funcionalidades:
    - Suporte a F11 para tela cheia
    - Detecção de múltiplos monitores
    - Gerenciamento de resoluções
    - Suporte ao Windows 7
    """
    
    def __init__(self, app: QApplication):
        """
        Inicializa o gerenciador de tela cheia
        
        Args:
            app: Instância da aplicação Qt
        """
        self.app = app
        self.windows: List[QMainWindow] = []
        self.fullscreen_windows: List[QMainWindow] = []
        self.monitors: List[MonitorInfo] = []
        
        # Detectar monitores
        self._detect_monitors()
        
        logger.info(f"Gerenciador de tela cheia inicializado com {len(self.monitors)} monitores")
    
    def _detect_monitors(self):
        """Detecta todos os monitores disponíveis"""
        self.monitors.clear()
        
        for screen in self.app.screens():
            monitor_info = MonitorInfo(screen)
            self.monitors.append(monitor_info)
            logger.info(f"Monitor detectado: {monitor_info}")
    
    def register_window(self, window: QMainWindow):
        """
        Registra uma janela para gerenciamento
        
        Args:
            window: Janela a ser registrada
        """
        if window not in self.windows:
            self.windows.append(window)
            
            # Instalar filtro de eventos para F11
            window.installEventFilter(self)
            
            logger.info(f"Janela registrada: {window.windowTitle()}")
    
    def unregister_window(self, window: QMainWindow):
        """
        Remove uma janela do gerenciamento
        
        Args:
            window: Janela a ser removida
        """
        if window in self.windows:
            self.windows.remove(window)
            window.removeEventFilter(self)
            
            if window in self.fullscreen_windows:
                self.fullscreen_windows.remove(window)
            
            logger.info(f"Janela removida: {window.windowTitle()}")
    
    def toggle_fullscreen(self, window: QMainWindow):
        """
        Alterna o modo tela cheia de uma janela
        
        Args:
            window: Janela para alternar tela cheia
        """
        if window.isFullScreen():
            self.exit_fullscreen(window)
        else:
            self.enter_fullscreen(window)
    
    def enter_fullscreen(self, window: QMainWindow):
        """
        Entra em modo tela cheia
        
        Args:
            window: Janela para entrar em tela cheia
        """
        if not window.isFullScreen():
            # Salvar geometria atual
            window.setProperty("previous_geometry", window.geometry())
            
            # Entrar em tela cheia
            window.showFullScreen()
            
            if window not in self.fullscreen_windows:
                self.fullscreen_windows.append(window)
            
            logger.info(f"Tela cheia ativada: {window.windowTitle()}")
    
    def exit_fullscreen(self, window: QMainWindow):
        """
        Sai do modo tela cheia
        
        Args:
            window: Janela para sair da tela cheia
        """
        if window.isFullScreen():
            # Restaurar geometria anterior
            previous_geometry = window.property("previous_geometry")
            if previous_geometry:
                window.setGeometry(previous_geometry)
            
            # Sair da tela cheia
            window.showNormal()
            
            if window in self.fullscreen_windows:
                self.fullscreen_windows.remove(window)
            
            logger.info(f"Tela cheia desativada: {window.windowTitle()}")
    
    def get_monitor_count(self) -> int:
        """
        Retorna o número de monitores
        
        Returns:
            int: Número de monitores
        """
        return len(self.monitors)
    
    def get_monitor_info(self, index: int = 0) -> Optional[MonitorInfo]:
        """
        Retorna informações de um monitor
        
        Args:
            index: Índice do monitor (0 = primário)
            
        Returns:
            MonitorInfo: Informações do monitor ou None
        """
        if 0 <= index < len(self.monitors):
            return self.monitors[index]
        return None
    
    def get_primary_monitor(self) -> Optional[MonitorInfo]:
        """
        Retorna o monitor primário
        
        Returns:
            MonitorInfo: Monitor primário ou None
        """
        return self.get_monitor_info(0)
    
    def get_monitor_for_window(self, window: QMainWindow) -> Optional[MonitorInfo]:
        """
        Retorna o monitor onde uma janela está localizada
        
        Args:
            window: Janela para verificar
            
        Returns:
            MonitorInfo: Monitor da janela ou None
        """
        window_center = window.geometry().center()
        
        for monitor in self.monitors:
            if monitor.geometry.contains(window_center):
                return monitor
        
        return None
    
    def move_window_to_monitor(self, window: QMainWindow, monitor_index: int):
        """
        Move uma janela para um monitor específico
        
        Args:
            window: Janela a ser movida
            monitor_index: Índice do monitor de destino
        """
        monitor = self.get_monitor_info(monitor_index)
        if monitor:
            # Calcular posição central no monitor
            monitor_center = monitor.geometry.center()
            window_rect = window.geometry()
            window_rect.moveCenter(monitor_center)
            
            window.setGeometry(window_rect)
            logger.info(f"Janela movida para monitor {monitor_index}")
    
    def eventFilter(self, obj, event):
        """
        Filtro de eventos para capturar F11
        
        Args:
            obj: Objeto que gerou o evento
            event: Evento capturado
            
        Returns:
            bool: True se evento foi processado
        """
        if isinstance(event, QKeyEvent):
            if event.type() == QKeyEvent.KeyPress:
                if event.key() == Qt.Key_F11:
                    # Encontrar a janela que gerou o evento
                    for window in self.windows:
                        if window == obj or window.isAncestorOf(obj):
                            self.toggle_fullscreen(window)
                            return True
        
        return False
    
    def get_fullscreen_windows(self) -> List[QMainWindow]:
        """
        Retorna lista de janelas em tela cheia
        
        Returns:
            List[QMainWindow]: Lista de janelas em tela cheia
        """
        return self.fullscreen_windows.copy()
    
    def is_fullscreen(self, window: QMainWindow) -> bool:
        """
        Verifica se uma janela está em tela cheia
        
        Args:
            window: Janela para verificar
            
        Returns:
            bool: True se está em tela cheia
        """
        return window in self.fullscreen_windows
    
    def cleanup(self):
        """Limpa recursos do gerenciador"""
        # Sair de todas as telas cheias
        for window in self.fullscreen_windows.copy():
            self.exit_fullscreen(window)
        
        # Remover todas as janelas
        for window in self.windows.copy():
            self.unregister_window(window)
        
        logger.info("Gerenciador de tela cheia finalizado")


# Função de conveniência para criar gerenciador
def create_fullscreen_manager(app: QApplication) -> FullscreenManager:
    """
    Cria uma instância do gerenciador de tela cheia
    
    Args:
        app: Instância da aplicação Qt
        
    Returns:
        FullscreenManager: Instância do gerenciador
    """
    return FullscreenManager(app)


if __name__ == "__main__":
    # Teste do gerenciador
    app = QApplication(sys.argv)
    
    manager = create_fullscreen_manager(app)
    
    # Criar janela de teste
    test_window = QMainWindow()
    test_window.setWindowTitle("Teste Tela Cheia")
    test_window.resize(800, 600)
    test_window.show()
    
    # Registrar janela
    manager.register_window(test_window)
    
    print(f"Número de monitores: {manager.get_monitor_count()}")
    for i, monitor in enumerate(manager.monitors):
        print(f"Monitor {i}: {monitor}")
    
    print("\nPressione F11 para alternar tela cheia")
    print("Pressione Ctrl+C para sair")
    
    try:
        sys.exit(app.exec_())
    except KeyboardInterrupt:
        manager.cleanup() 