import gxipy as gx
import cv2
import numpy as np
import time


def main():
    print("Инициализация камер...")
    
    # Создаем менеджер устройств
    device_manager = gx.DeviceManager()
    dev_num, dev_info_list = device_manager.update_all_device_list()
    
    if dev_num < 2:
        print("Найдено только %d камер. Нужно 2 камеры!" % dev_num)
        return

    # Открываем обе камеры
    cam1 = device_manager.open_device_by_index(1)
    cam2 = device_manager.open_device_by_index(2)
    
    # Список разрешений (ширина, высота) для переключения
    resolutions = [
        (640, 480),
        (800, 600), 
        (1024, 768),
        (1280, 960),
        (1440, 1080)
    ]
    current_res_index = 0
    
    # Переменные для FPS и статистики
    fps1 = 0
    fps2 = 0
    frame_count1 = 0
    frame_count2 = 0
    last_time = time.time()
    data_rate1 = 0
    data_rate2 = 0
    
    def set_resolution(cam1, cam2, width, height, cam_num):
        try:
            cam1.stream_off()
            cam2.stream_off()
            
            cam1.Width.set(width)
            cam1.Height.set(height)
            cam2.Width.set(width)
            cam2.Height.set(height)
            
            cam1.stream_on()
            cam2.stream_on()
            
            print("Камеры %d: установлено разрешение %dx%d" % (cam_num, width, height))
            return True
        except Exception as e:
            print("Ошибка установки разрешения: %s" % str(e))
            # Пробуем перезапустить стримы даже при ошибке
            try:
                cam1.stream_on()
                cam2.stream_on()
            except:
                pass
            return False
    
    # Устанавливаем начальное разрешение
    width, height = resolutions[current_res_index]
    set_resolution(cam1, cam2, width, height, 1)
    
    remote_device_feature1 = cam1.get_remote_device_feature_control()
    remote_device_feature2 = cam2.get_remote_device_feature_control()    
    
    # Только читаем текущие значения для каждой камеры
    exposure_time_feature1 = remote_device_feature1.get_float_feature("ExposureTime") 
    exposure_time_feature2 = remote_device_feature2.get_float_feature("ExposureTime")    
    print("Камера 1 экспозиция: %s" % exposure_time_feature1.get())
    print("Камера 2 экспозиция: %s" % exposure_time_feature2.get())    
    gain_value1 = remote_device_feature1.get_float_feature("Gain")
    gain_value2 = remote_device_feature2.get_float_feature("Gain")
    print("Камера 1 gain: %s" % gain_value1.get())
    print("Камера 2 gain: %s" % gain_value2.get())
    
    # Настраиваем обе камеры
    for cam in [cam1, cam2]:
        cam.TriggerMode.set(0)  # Непрерывный режим
    
    print("Горячие клавиши:")
    print("'w' - увеличить разрешение")
    print("'s' - уменьшить разрешение") 
    print("'q' - выход")
    print("Текущее разрешение: %dx%d" % (width, height))

    try:
        while True:
            current_time = time.time()
            time_diff = current_time - last_time
            
            # Обновляем FPS каждую секунду
            if time_diff >= 1.0:
                fps1 = frame_count1 / time_diff
                fps2 = frame_count2 / time_diff
                frame_count1 = 0
                frame_count2 = 0
                last_time = current_time
                
                # Рассчитываем скорость передачи данных (в мегабитах/сек)
                # Предполагаем 8 бит на пиксель (MONO8)
                pixels_per_frame = width * height
                bits_per_frame = pixels_per_frame * 8
                data_rate1 = fps1 * bits_per_frame / 1000000  # Мбит/с
                data_rate2 = fps2 * bits_per_frame / 1000000  # Мбит/с
            
            # Получаем изображения с обеих камер
            raw_image1 = cam1.data_stream[0].get_image()
            raw_image2 = cam2.data_stream[0].get_image()
            
            # Обрабатываем первую камеру
            if raw_image1 is not None:
                numpy_image1 = raw_image1.get_numpy_array()
                if numpy_image1 is not None:
                    frame_count1 += 1
                    
                    # Добавляем текст с информацией поверх изображения
                    display_img1 = numpy_image1.copy()
                    
                    # Создаем многострочный текст
                    info_texts = [
                        "Res: %dx%d" % (width, height),
                        "FPS: %.1f" % fps1,
                        "Data: %.1f Mbps" % data_rate1
                    ]
                    
                    # Отображаем каждую строку текста
                    y_offset = 30
                    for text in info_texts:
                        cv2.putText(display_img1, text, (10, y_offset), 
                                   cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
                        y_offset += 25
                    
                    cv2.imshow('Camera 1', display_img1)
            
            # Обрабатываем вторую камеру
            if raw_image2 is not None:
                numpy_image2 = raw_image2.get_numpy_array()
                if numpy_image2 is not None:
                    frame_count2 += 1
                    
                    display_img2 = numpy_image2.copy()
                    
                    # Создаем многострочный текст
                    info_texts = [
                        "Res: %dx%d" % (width, height),
                        "FPS: %.1f" % fps2,
                        "Data: %.1f Mbps" % data_rate2
                    ]
                    
                    # Отображаем каждую строку текста
                    y_offset = 30
                    for text in info_texts:
                        cv2.putText(display_img2, text, (10, y_offset), 
                                   cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 255), 2)
                        y_offset += 25
                    
                    cv2.imshow('Camera 2', display_img2)
            
            # Обработка горячих клавиш
            key = cv2.waitKey(1) & 0xFF
            
            if key == ord('q'):
                break
            elif key == ord('w'):  # W - увеличить разрешение
                if current_res_index < len(resolutions) - 1:
                    current_res_index += 1
                    width, height = resolutions[current_res_index]
                    if set_resolution(cam1, cam2, width, height, current_res_index + 1):
                        print("Текущее разрешение: %dx%d" % (width, height))
                        # Сбрасываем счетчики FPS при смене разрешения
                        frame_count1 = 0
                        frame_count2 = 0
                        last_time = time.time()
            elif key == ord('s'):  # S - уменьшить разрешение
                if current_res_index > 0:
                    current_res_index -= 1
                    width, height = resolutions[current_res_index]
                    if set_resolution(cam1, cam2, width, height, current_res_index + 1):
                        print("Текущее разрешение: %dx%d" % (width, height))
                        # Сбрасываем счетчики FPS при смене разрешения
                        frame_count1 = 0
                        frame_count2 = 0
                        last_time = time.time()
                
    except KeyboardInterrupt:
        print("Прервано пользователем")
    
    finally:
        # Очистка
        cv2.destroyAllWindows()
        cam1.stream_off()
        cam2.stream_off()
        cam1.close_device()
        cam2.close_device()
        print("Камеры отключены")


if __name__ == "__main__":
    main()