import sys
import cv2
import atexit
import threading
import numpy as np


class Camera():
    def __init__(self):
        self.value = np.empty((224, 224, 3), dtype=np.uint8)
        self.capture_width = 224
        self.capture_height = 224
        self.fps = 21
        self.width = 224
        self.height = 224
        self.count = 0

        try:
            self.cap = cv2.VideoCapture(self._gst_str(), cv2.CAP_GSTREAMER)

            re, image = self.cap.read()

            if not re:
                raise RuntimeError('Could not read image from camera.')

            self.value = image
            self.start()

        except:
            self.stop()
            raise RuntimeError('Could not initialize camera')

        atexit.register(self.stop)

    def _capture_frames(self):
        while True:
            re, image = self.cap.read()
            if re:
                self.value = image
                self.count += 1
            else:
                break

    def _gst_str(self):
        return ('nvarguscamerasrc ! '
                'video/x-raw(memory:NVMM), '
                'width=(int)%d, height=(int)%d, '
                'format=(string)NV12, framerate=(fraction)%d/1 ! '
                'nvvidconv flip-method=%d ! '
                'video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! '
                'videoconvert ! '
                'video/x-raw, format=(string)BGR ! appsink' % (self.capture_width, self.capture_height, self.fps, 2, self.capture_width, self.capture_height))

    def start(self):
        if not self.cap.isOpened():
            self.cap.open(self._gst_str(), cv2.CAP_GSTREAMER)
        if not hasattr(self, 'thread') or not self.thread.isAlive():
            self.thread = threading.Thread(target=self._capture_frames)
            # self.thread.daemon = True
            self.thread.start()

    def stop(self):
        if hasattr(self, 'cap'):
            self.cap.release()
        if hasattr(self, 'thread'):
            self.thread.join()

    # def restart(self):
    #     self.stop()
    #     self.start()


if __name__ == "__main__":
    cam = Camera()

    try:
        while True:
            print(cam.count)

    except KeyboardInterrupt:
        sys.exit(0)
