# Basler pylon SDK를 별도로 설치해야 합니다.
# 설치 방법: https://www.baslerweb.com/en/downloads/software-downloads/
# SDK 설치 후: pip install pypylon
import numpy as np
from pypylon import pylon


class BaslerCamera:
    def __init__(self):
        self.camera = None

    def connect(self):
        """첫 번째 Basler 장치에 연결, ExposureAuto=Continuous"""
        try:
            self.camera = pylon.InstantCamera(
                pylon.TlFactory.GetInstance().CreateFirstDevice()
            )
            self.camera.Open()
            self.camera.ExposureAuto.SetValue("Continuous")
            print("[Basler] 연결 성공")
        except Exception as e:
            print(f"[Basler] 연결 실패: {e}")
            self.camera = None

    def disconnect(self):
        if self.camera and self.camera.IsOpen():
            try:
                self.camera.Close()
            except Exception:
                pass
            print("[Basler] 연결 종료")

    def is_connected(self) -> bool:
        return self.camera is not None and self.camera.IsOpen()

    def capture(self) -> np.ndarray:
        """단일 프레임 촬영 — GrabOne() 사용 (모든 카메라 모델 호환)"""
        if not self.camera:
            return None
        try:
            with self.camera.GrabOne(5000) as result:
                if result.GrabSucceeded():
                    return result.Array.copy()
        except Exception as e:
            print(f"[Basler] capture 오류: {e}")
        return None

    def start_continuous(self):
        """GrabStrategy_LatestImageOnly로 연속 grab 시작"""
        if self.camera:
            self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)

    def grab_latest(self) -> np.ndarray:
        """최신 프레임 반환"""
        if not self.camera or not self.camera.IsGrabbing():
            return None
        try:
            with self.camera.RetrieveResult(1000) as result:
                if result.GrabSucceeded():
                    return result.Array.copy()
        except Exception as e:
            print(f"[Basler] grab_latest 오류: {e}")
        return None

    def stop_continuous(self):
        if self.camera:
            self.camera.StopGrabbing()
