from threading import Thread
import time, numpy as np, cv2

class Camera(object):
    def __init__(self, width, height, framerate, log=None,channel=0,flip=None):
        self.__log = self.__log if log is None else log
        self.__isCaptured = False
        self.__frame = None
        self.isOpened = False
        self.width = width
        self.height = height
        self.framerate = framerate
        self.channel = channel
        self.flip = flip
        self.__thread = Thread(target=self.__job)
    def start(self):
        self.__isCaptured = False
        self.__frame = None
        self.isOpened = True
        self.__thread.start()
    def stop(self):
        self.__isCaptured = False
        self.__frame = None
        self.isOpened = False
    def capture(self):
        return self.__isCaptured, self.__frame
    def __job(self):
        w = self.width
        h = self.height
        fps = self.framerate
        dev = cv2.VideoCapture(self.channel,cv2.CAP_V4L2)
        while self.isOpened:
            if dev.isOpened():
                ret, frame = dev.read()
                if not ret:
                    break
                if(self.flip is not None):
                    self.__frame = cv2.flip(frame, self.flip)
                else:
                    self.__frame = frame
                self.__isCaptured = ret
                time.sleep(1 / fps)
        dev.release()
        self.__isCaptured = False
        self.__frame = None
        self.__log("camera stop")
    def __gstreamer(self, width, height, framerate, flip_method=2):
        return (
           f'nvarguscamerasrc ! video/x-raw(memory:NVMM), ' +
           f'width=(int){width}, height=(int){height}, ' +
           f'format=(string)NV12, framerate=(fraction){framerate}/1 ! ' +
           f'nvvidconv flip-method={flip_method} ! ' +
           f'video/x-raw, width=(int){width}, height=(int){height}, format=(string)BGRx ! ' +
           'videoconvert ! video/x-raw, format=(string)BGR ! appsink')
    def __log(self, message):
        print(message)
