from PyQt5 import QtCore, QtGui, QtWidgets, uic
import sys
import cv2
import numpy as np
import threading
import time
import queue
import re

from recordsave import Recorder
from ssd_engine import SSD_Detector
from motiondetector import MotionDetector
from settings import EmailSender

# Title
WINDOW_TITLE = "DeepEye v1.1 2018"

# Cam Params
CAM_INDEX = 0
CAM_WIDTH = 1280
CAM_HEIGHT = 720
CAM_FPS = 30

# (record everything mode) This parameter determines the intervals of recording
RECORD_INTERVAL = 120 # in seconds

# (smart recording mode) This parameter determines how many more frames to save after inactivity
RECORD_EXTENSION = 60 # in frame counts

# Threading variables
cam_running = False
capture_thread = None
q = queue.Queue()

# load UI
form_class = uic.loadUiType("interface.ui")[0]

# parallel threaded camera feed
def grab(cam, queue, width, height, fps):
    global cam_running
    cam_running = True

    capture = cv2.VideoCapture(cam)
    capture.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    capture.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    capture.set(cv2.CAP_PROP_FPS, fps)

    while(cam_running):
        frame = {}        
        capture.grab()
        retval, img = capture.retrieve(0)
        frame["img"] = img

        if queue.qsize() < 10:
            queue.put(frame)
        else:
            print (queue.qsize())

    print("Terminated camera feed")
    

class MyWindowClass(QtWidgets.QMainWindow, form_class):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.setFixedSize(self.size())

        # obtain dim of elements
        self.triggerGroupDim = [self.triggerGroup.geometry().width(),self.triggerGroup.geometry().height()]
        self.recordButtonDim = [self.recordButton.geometry().width(),self.recordButton.geometry().height()]
        self.filepathTextDim = [self.filepathText.geometry().width(),self.filepathText.geometry().height()]

        # Livefeed tab:
        self.window_width = self.live_display.frameSize().width()
        self.window_height = self.live_display.frameSize().height()
        self.live_display.setStyleSheet("QLabel { background-color : black}")  

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_frame)
        self.timer.start(1)

        self.datetimeTagLocation = (10,30)
        self.datetimeTagColour = (0,255,0)

        # Recorder object
        self.record = Recorder(CAM_WIDTH, CAM_HEIGHT, CAM_FPS)
        self.recordButton.clicked.connect(self.record_to)
        self.timetracker = -1

        self.subjectCheck.stateChanged.connect(self.record_on_detection)
        self.recordOnPresence = False
        self.inactiveCount = 0
        self.isDetected = False

        self.motionCheck.stateChanged.connect(self.record_on_motion)
        self.recordOnMotion = False
        self.isMoving = False
        self.noMotionCount = 0

        self.motionTagLocation = (CAM_WIDTH-300,30)
        self.motionTagColour = (0,0,255)

        # Detector object
        self.detector = SSD_Detector()
        if not self.detector.ready:
            self.subjectCheck.setEnabled(False)

        # Motion detector object
        self.motiondetect = MotionDetector()

        # email alert module
        self.emailsender = EmailSender()
        self.sendOnActivity = False
        self.sendoutStartTime = -1

        self.emailsetupButton.clicked.connect(self.emailAlertSetup)
        self.testemailButton.clicked.connect(self.emailSendTest)
        self.sendemailCheck.stateChanged.connect(self.emailSendToggleFunc)
        self.password_input.setEchoMode(QtWidgets.QLineEdit.Password)
        self.port_input.setValidator(QtGui.QIntValidator(0,999))

        if self.emailsender.getSetupFlag():
            email_address, email_password, smtp, port = self.emailsender.getLoginDetails()
            self.email_input.setText(email_address)
            self.password_input.setText(email_password)
            self.smtp_input.setText(smtp)
            self.port_input.setText(str(port))

            # Disable user interface
            self.emailGroup.setEnabled(False)
            self.testemailButton.setEnabled(True)
            self.sendemailCheck.setEnabled(True)
            self.emailsetupButton.setText("Change")

    def emailSendToggleFunc(self):
        if self.sendemailCheck.isChecked():
            self.sendOnActivity = True
        else:
            self.sendOnActivity = False
            self.sendoutStartTime = -1

    def emailSendTest(self):
        if self.emailsender.getSetupFlag():
            self.emailsender.send_testmsg()

    def emailAlertSetup(self):
        if self.emailsetupButton.text() == "Setup":
            if not self.emailsender.getSetupFlag():
                email_address = self.email_input.text()
                email_password = self.password_input.text()
                smtp = self.smtp_input.text()
                port = self.port_input.text()

                # simple check to evaluate input validity
                check_email_pattern = re.compile('[^@]+@[^@]+\.[^@]+')
                if not check_email_pattern.match(email_address):
                    self.err_email_label.setText("Invalid Email")
                else:
                    self.err_email_label.setText("")
                    self.emailsender.login_setup(email_address,email_password,smtp,int(port))

                    if self.emailsender.getSetupFlag():

                        # If successfully logged in
                        self.emailGroup.setEnabled(False)
                        self.testemailButton.setEnabled(True)
                        self.sendemailCheck.setEnabled(True)
                        self.emailsetupButton.setText("Change")
                    else:
                        # authentication failed
                        self.err_email_label.setText("Authentication Failed!")
        else:
            self.emailsender.close_connection()
            self.emailGroup.setEnabled(True)
            self.testemailButton.setEnabled(False)
            self.sendemailCheck.setEnabled(False)
            self.emailsetupButton.setText("Setup")
            
    def emailSendTracker(self, isDetected):
        currentDateTime = QtCore.QTime.currentTime().toString(QtCore.Qt.DefaultLocaleLongDate).split()
        currentDayLight = currentDateTime[1]
        currentTime = currentDateTime[0].split(':')
        currentTimeSeconds = int(currentTime[0])*3600 + int(currentTime[1])*60 + int(currentTime[2])

        if isDetected:
            if self.sendoutStartTime == -1: # initialize
                # send out first email here
                print("Activity started: Send out first email")
                self.emailsender.send_emailalert(True,currentTimeSeconds,currentDayLight)

            self.sendoutStartTime = currentTimeSeconds
        else:
            # invoke timeout sequence (2 mins of inactivity, send out last email)
            if self.sendoutStartTime > -1:

                if currentTimeSeconds - self.sendoutStartTime > RECORD_INTERVAL:

                    print("Activity ended: Send out last email")
                    self.emailsender.send_emailalert(False,currentTimeSeconds,currentDayLight)

                    self.sendoutStartTime = -1


    def resizeEvent(self,event):
        # readjust ui according to window size
        # MainWindow.textEdit.setGeometry(QtCore.QRect(30, 80, 341, 441))

        curr_mainframe_w = self.frameSize().width()
        curr_mainframe_h = self.frameSize().height()

        # Adjust tab widget size
        fixed_tab_x = self.tabWidget.geometry().x()
        fixed_tab_y = self.tabWidget.geometry().y()
        new_tab_w = curr_mainframe_w - 40
        new_tab_h = curr_mainframe_h - 80

        self.tabWidget.resize(new_tab_w,new_tab_h)

        # **** Set all elements relative to tabWidget_relativeSizeRatio ****

        # set triggerGroup Pos:
        new_trigger_x = fixed_tab_x + (new_tab_w - self.triggerGroupDim[0] - 40)
        new_trigger_y = fixed_tab_y
        self.triggerGroup.move(new_trigger_x,new_trigger_y)

        # set recordButton Pos:
        new_recordbtn_x = fixed_tab_x + (new_tab_w/2 - self.recordButtonDim[0])
        new_recordbtn_y = fixed_tab_y + (new_tab_h - self.recordButtonDim[1] - 80)
        self.recordButton.move(new_recordbtn_x,new_recordbtn_y)

        # set filePath Pos:
        new_filepath_x = fixed_tab_x
        new_filepath_y = new_recordbtn_y - self.filepathTextDim[1] - 20
        self.filepathText.move(new_filepath_x,new_filepath_y)

        # finally set the display size
        self.window_width = new_trigger_x - 40
        self.window_height = new_filepath_y - 40
        self.live_display.resize(self.window_width,self.window_height)

    def record_to(self):

        if self.record.getPreDefinedFilePath() == "undefined":
            # return filepath where video is saved
            dir_ = QtWidgets.QFileDialog.getExistingDirectory(None, 'Select a folder for record output:', '~/', QtWidgets.QFileDialog.ShowDirsOnly)

            if len(dir_) > 0:
                self.record.setPreDefinedFilePath(dir_)
                self.filepathText.setText('Saving video to: ' + dir_)
            else:
                self.record.setPreDefinedFilePath("undefined")

        else:
            if self.record.getRecordingStatus():
                # stop recording
                self.record.turnOffRecording()
                self.recordButton.setText('Record')
            else:
                self.record.invokeRecording()

                if self.record.getRecordingStatus():
                    self.recordButton.setText('Stop')

    def record_on_detection(self):
        if self.subjectCheck.isChecked():
            self.recordOnPresence = True
        else:
            self.recordOnPresence = False

    def record_on_motion(self):
        if self.motionCheck.isChecked():
            self.recordOnMotion = True
        else:
            self.recordOnMotion = False

    def recordTriggerFunc(self, frame):
        # record on presence only
        if self.recordOnPresence and not self.recordOnMotion:
            if self.isDetected:

                if self.inactiveCount >= RECORD_INTERVAL: # estimate 2 sec of detect nothing
                    self.record.invokeRecording() #reinitalize

                self.record.vidWriter.write(frame)
                self.inactiveCount = 0
            else:

                if self.inactiveCount < RECORD_INTERVAL:
                    self.inactiveCount += 1
                else:
                    self.record.killRecorder()

        elif self.recordOnMotion and not self.recordOnPresence:
            if self.isMoving:
                if self.noMotionCount >= RECORD_INTERVAL:
                    self.record.invokeRecording()

                self.record.vidWriter.write(frame)
                self.noMotionCount = 0
            else:
                if self.noMotionCount < RECORD_INTERVAL:
                    self.noMotionCount += 1
                else:
                    self.record.killRecorder()

        elif self.recordOnMotion and self.recordOnPresence:
            if self.isDetected or self.isMoving:
                if self.inactiveCount >= RECORD_INTERVAL and self.noMotionCount >= RECORD_INTERVAL:
                    self.record.invokeRecording()
                self.record.vidWriter.write(frame)
                self.inactiveCount = 0
                self.noMotionCount = 0
            else:
                assessOne = False
                assessTwo = False

                if self.noMotionCount < RECORD_INTERVAL:
                    self.noMotionCount += 1
                else:
                    assessOne = True
                if self.inactiveCount < RECORD_INTERVAL:
                    self.inactiveCount += 1
                else:
                    assessTwo = True

                if assessOne and assessTwo:
                    self.record.killRecorder()
        else:
            # Record everything in interval of 2 minutes
            if self.timetracker == -1:
                self.timetracker = self.record.getCurrentTime()
            else:
                ref_hr, ref_min, ref_sec, _ = self.timetracker.split('_')
                refTimeInSeconds = int(ref_min)*60 + int(ref_sec)

                cur_hr, cur_min, cur_sec, _ = self.record.getCurrentTime().split('_')
                curTimeInSeconds = int(cur_min)*60 + int(cur_sec)

                if curTimeInSeconds - refTimeInSeconds >= RECORD_INTERVAL:
                    self.record.invokeRecording()
                    self.timetracker = self.record.getCurrentTime()
            
            self.record.vidWriter.write(frame)



    def drawOnFrame(self, inputImg, isMotion):
        # Tag date
        cv2.putText(inputImg,self.record.getDisplayLabel(),
                        self.datetimeTagLocation, 
                        cv2.FONT_HERSHEY_SIMPLEX, 
                        1,
                        self.datetimeTagColour,
                        2,
                        cv2.LINE_AA)

        # Tag motion indicator        
        if isMotion:
            cv2.putText(inputImg,"Motion Detected!",
                            self.motionTagLocation, 
                            cv2.FONT_HERSHEY_SIMPLEX, 
                            1,
                            self.motionTagColour,
                            2,
                            cv2.LINE_AA)            

    def displayFrame(self, img):
        img_height, img_width, img_colors = img.shape

        scale_w = float(self.window_width) / float(img_width)
        scale_h = float(self.window_height) / float(img_height)
        scale = min([scale_w, scale_h])

        if scale == 0:
            scale = 1
        
        img = cv2.resize(img, None, fx=scale, fy=scale, interpolation = cv2.INTER_CUBIC)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        height, width, bpc = img.shape
        bpl = bpc * width
        image = QtGui.QImage(img.data, width, height, bpl, QtGui.QImage.Format_RGB888)
        pix = QtGui.QPixmap(image)
        self.live_display.setPixmap(pix)

    # Live Mode
    def update_frame(self):
        if not q.empty():

            # UI thingy
            self.recordButton.setEnabled(True)

            # grab frame from video thread
            try:
                frame = q.get()
                img = frame["img"]
            except:
                print("error obtaining images")
            else:
                # detect motion
                if self.recordOnMotion:
                    # detect motion
                    motionImg = img.copy()
                    self.isMoving = self.motiondetect.detectmotion(motionImg)
                else:
                    self.isMoving = False

                # detect presence
                if self.recordOnPresence:
                    # detect objects and indicate on display
                    img, self.isDetected = self.detector.process_image(img)
                else:
                    self.isDetected = False

                if self.sendOnActivity:
                    if self.isMoving or self.isDetected:
                        self.emailSendTracker(True)
                    else:
                        self.emailSendTracker(False)


                # Tag the frame with indications
                self.drawOnFrame(img,self.isMoving)

                if self.record.getRecordingStatus():
                    self.recordTriggerFunc(img)

                # show frame with annotation
                self.displayFrame(img)


    def closeEvent(self, event):
        global cam_running
        cam_running = False
        self.record.killRecorder()


def main():
    capture_thread = threading.Thread(target=grab, args = (CAM_INDEX, q, CAM_WIDTH, CAM_HEIGHT, CAM_FPS))
    capture_thread.start()

    app = QtWidgets.QApplication(sys.argv)
    w = MyWindowClass(None)
    w.setWindowTitle(WINDOW_TITLE)
    w.show()
    app.exec_()

main()

from PyQt5 import QtCore, QtGui, QtWidgets, uic
import sys
import cv2
import numpy as np
import threading
import time
import queue
import re

from recordsave import Recorder
from ssd_engine import SSD_Detector
from motiondetector import MotionDetector
from settings import EmailSender

# Title
WINDOW_TITLE = "DeepEye v1.1 2018"

# Cam Params
CAM_INDEX = 0
CAM_WIDTH = 1280
CAM_HEIGHT = 720
CAM_FPS = 30

# (record everything mode) This parameter determines the intervals of recording
RECORD_INTERVAL = 120 # in seconds

# (smart recording mode) This parameter determines how many more frames to save after inactivity
RECORD_EXTENSION = 60 # in frame counts

# Threading variables
cam_running = False
capture_thread = None
q = queue.Queue()

# load UI
form_class = uic.loadUiType("interface.ui")[0]

# parallel threaded camera feed
def grab(cam, queue, width, height, fps):
    global cam_running
    cam_running = True

    capture = cv2.VideoCapture(cam)
    capture.set(cv2.CAP_PROP_FRAME_WIDTH, width)
    capture.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
    capture.set(cv2.CAP_PROP_FPS, fps)

    while(cam_running):
        frame = {}        
        capture.grab()
        retval, img = capture.retrieve(0)
        frame["img"] = img

        if queue.qsize() < 10:
            queue.put(frame)
        else:
            print (queue.qsize())

    print("Terminated camera feed")
    

class MyWindowClass(QtWidgets.QMainWindow, form_class):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.setFixedSize(self.size())

        # obtain dim of elements
        self.triggerGroupDim = [self.triggerGroup.geometry().width(),self.triggerGroup.geometry().height()]
        self.recordButtonDim = [self.recordButton.geometry().width(),self.recordButton.geometry().height()]
        self.filepathTextDim = [self.filepathText.geometry().width(),self.filepathText.geometry().height()]

        # Livefeed tab:
        self.window_width = self.live_display.frameSize().width()
        self.window_height = self.live_display.frameSize().height()
        self.live_display.setStyleSheet("QLabel { background-color : black}")  

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.update_frame)
        self.timer.start(1)

        self.datetimeTagLocation = (10,30)
        self.datetimeTagColour = (0,255,0)

        # Recorder object
        self.record = Recorder(CAM_WIDTH, CAM_HEIGHT, CAM_FPS)
        self.recordButton.clicked.connect(self.record_to)
        self.timetracker = -1

        self.subjectCheck.stateChanged.connect(self.record_on_detection)
        self.recordOnPresence = False
        self.inactiveCount = 0
        self.isDetected = False

        self.motionCheck.stateChanged.connect(self.record_on_motion)
        self.recordOnMotion = False
        self.isMoving = False
        self.noMotionCount = 0

        self.motionTagLocation = (CAM_WIDTH-300,30)
        self.motionTagColour = (0,0,255)

        # Detector object
        self.detector = SSD_Detector()
        if not self.detector.ready:
            self.subjectCheck.setEnabled(False)

        # Motion detector object
        self.motiondetect = MotionDetector()

        # email alert module
        self.emailsender = EmailSender()
        self.sendOnActivity = False
        self.sendoutStartTime = -1

        self.emailsetupButton.clicked.connect(self.emailAlertSetup)
        self.testemailButton.clicked.connect(self.emailSendTest)
        self.sendemailCheck.stateChanged.connect(self.emailSendToggleFunc)
        self.password_input.setEchoMode(QtWidgets.QLineEdit.Password)
        self.port_input.setValidator(QtGui.QIntValidator(0,999))

        if self.emailsender.getSetupFlag():
            email_address, email_password, smtp, port = self.emailsender.getLoginDetails()
            self.email_input.setText(email_address)
            self.password_input.setText(email_password)
            self.smtp_input.setText(smtp)
            self.port_input.setText(str(port))

            # Disable user interface
            self.emailGroup.setEnabled(False)
            self.testemailButton.setEnabled(True)
            self.sendemailCheck.setEnabled(True)
            self.emailsetupButton.setText("Change")

    def emailSendToggleFunc(self):
        if self.sendemailCheck.isChecked():
            self.sendOnActivity = True
        else:
            self.sendOnActivity = False
            self.sendoutStartTime = -1

    def emailSendTest(self):
        if self.emailsender.getSetupFlag():
            self.emailsender.send_testmsg()

    def emailAlertSetup(self):
        if self.emailsetupButton.text() == "Setup":
            if not self.emailsender.getSetupFlag():
                email_address = self.email_input.text()
                email_password = self.password_input.text()
                smtp = self.smtp_input.text()
                port = self.port_input.text()

                # simple check to evaluate input validity
                check_email_pattern = re.compile('[^@]+@[^@]+\.[^@]+')
                if not check_email_pattern.match(email_address):
                    self.err_email_label.setText("Invalid Email")
                else:
                    self.err_email_label.setText("")
                    self.emailsender.login_setup(email_address,email_password,smtp,int(port))

                    if self.emailsender.getSetupFlag():

                        # If successfully logged in
                        self.emailGroup.setEnabled(False)
                        self.testemailButton.setEnabled(True)
                        self.sendemailCheck.setEnabled(True)
                        self.emailsetupButton.setText("Change")
                    else:
                        # authentication failed
                        self.err_email_label.setText("Authentication Failed!")
        else:
            self.emailsender.close_connection()
            self.emailGroup.setEnabled(True)
            self.testemailButton.setEnabled(False)
            self.sendemailCheck.setEnabled(False)
            self.emailsetupButton.setText("Setup")
            
    def emailSendTracker(self, isDetected):
        currentDateTime = QtCore.QTime.currentTime().toString(QtCore.Qt.DefaultLocaleLongDate).split()
        currentDayLight = currentDateTime[1]
        currentTime = currentDateTime[0].split(':')
        currentTimeSeconds = int(currentTime[0])*3600 + int(currentTime[1])*60 + int(currentTime[2])

        if isDetected:
            if self.sendoutStartTime == -1: # initialize
                # send out first email here
                print("Activity started: Send out first email")
                self.emailsender.send_emailalert(True,currentTimeSeconds,currentDayLight)

            self.sendoutStartTime = currentTimeSeconds
        else:
            # invoke timeout sequence (2 mins of inactivity, send out last email)
            if self.sendoutStartTime > -1:

                if currentTimeSeconds - self.sendoutStartTime > RECORD_INTERVAL:

                    print("Activity ended: Send out last email")
                    self.emailsender.send_emailalert(False,currentTimeSeconds,currentDayLight)

                    self.sendoutStartTime = -1


    def resizeEvent(self,event):
        # readjust ui according to window size
        # MainWindow.textEdit.setGeometry(QtCore.QRect(30, 80, 341, 441))

        curr_mainframe_w = self.frameSize().width()
        curr_mainframe_h = self.frameSize().height()

        # Adjust tab widget size
        fixed_tab_x = self.tabWidget.geometry().x()
        fixed_tab_y = self.tabWidget.geometry().y()
        new_tab_w = curr_mainframe_w - 40
        new_tab_h = curr_mainframe_h - 80

        self.tabWidget.resize(new_tab_w,new_tab_h)

        # **** Set all elements relative to tabWidget_relativeSizeRatio ****

        # set triggerGroup Pos:
        new_trigger_x = fixed_tab_x + (new_tab_w - self.triggerGroupDim[0] - 40)
        new_trigger_y = fixed_tab_y
        self.triggerGroup.move(new_trigger_x,new_trigger_y)

        # set recordButton Pos:
        new_recordbtn_x = fixed_tab_x + (new_tab_w/2 - self.recordButtonDim[0])
        new_recordbtn_y = fixed_tab_y + (new_tab_h - self.recordButtonDim[1] - 80)
        self.recordButton.move(new_recordbtn_x,new_recordbtn_y)

        # set filePath Pos:
        new_filepath_x = fixed_tab_x
        new_filepath_y = new_recordbtn_y - self.filepathTextDim[1] - 20
        self.filepathText.move(new_filepath_x,new_filepath_y)

        # finally set the display size
        self.window_width = new_trigger_x - 40
        self.window_height = new_filepath_y - 40
        self.live_display.resize(self.window_width,self.window_height)

    def record_to(self):

        if self.record.getPreDefinedFilePath() == "undefined":
            # return filepath where video is saved
            dir_ = QtWidgets.QFileDialog.getExistingDirectory(None, 'Select a folder for record output:', '~/', QtWidgets.QFileDialog.ShowDirsOnly)

            if len(dir_) > 0:
                self.record.setPreDefinedFilePath(dir_)
                self.filepathText.setText('Saving video to: ' + dir_)
            else:
                self.record.setPreDefinedFilePath("undefined")

        else:
            if self.record.getRecordingStatus():
                # stop recording
                self.record.turnOffRecording()
                self.recordButton.setText('Record')
            else:
                self.record.invokeRecording()

                if self.record.getRecordingStatus():
                    self.recordButton.setText('Stop')

    def record_on_detection(self):
        if self.subjectCheck.isChecked():
            self.recordOnPresence = True
        else:
            self.recordOnPresence = False

    def record_on_motion(self):
        if self.motionCheck.isChecked():
            self.recordOnMotion = True
        else:
            self.recordOnMotion = False

    def recordTriggerFunc(self, frame):
        # record on presence only
        if self.recordOnPresence and not self.recordOnMotion:
            if self.isDetected:

                if self.inactiveCount >= RECORD_INTERVAL: # estimate 2 sec of detect nothing
                    self.record.invokeRecording() #reinitalize

                self.record.vidWriter.write(frame)
                self.inactiveCount = 0
            else:

                if self.inactiveCount < RECORD_INTERVAL:
                    self.inactiveCount += 1
                else:
                    self.record.killRecorder()

        elif self.recordOnMotion and not self.recordOnPresence:
            if self.isMoving:
                if self.noMotionCount >= RECORD_INTERVAL:
                    self.record.invokeRecording()

                self.record.vidWriter.write(frame)
                self.noMotionCount = 0
            else:
                if self.noMotionCount < RECORD_INTERVAL:
                    self.noMotionCount += 1
                else:
                    self.record.killRecorder()

        elif self.recordOnMotion and self.recordOnPresence:
            if self.isDetected or self.isMoving:
                if self.inactiveCount >= RECORD_INTERVAL and self.noMotionCount >= RECORD_INTERVAL:
                    self.record.invokeRecording()
                self.record.vidWriter.write(frame)
                self.inactiveCount = 0
                self.noMotionCount = 0
            else:
                assessOne = False
                assessTwo = False

                if self.noMotionCount < RECORD_INTERVAL:
                    self.noMotionCount += 1
                else:
                    assessOne = True
                if self.inactiveCount < RECORD_INTERVAL:
                    self.inactiveCount += 1
                else:
                    assessTwo = True

                if assessOne and assessTwo:
                    self.record.killRecorder()
        else:
            # Record everything in interval of 2 minutes
            if self.timetracker == -1:
                self.timetracker = self.record.getCurrentTime()
            else:
                ref_hr, ref_min, ref_sec, _ = self.timetracker.split('_')
                refTimeInSeconds = int(ref_min)*60 + int(ref_sec)

                cur_hr, cur_min, cur_sec, _ = self.record.getCurrentTime().split('_')
                curTimeInSeconds = int(cur_min)*60 + int(cur_sec)

                if curTimeInSeconds - refTimeInSeconds >= RECORD_INTERVAL:
                    self.record.invokeRecording()
                    self.timetracker = self.record.getCurrentTime()
            
            self.record.vidWriter.write(frame)



    def drawOnFrame(self, inputImg, isMotion):
        # Tag date
        cv2.putText(inputImg,self.record.getDisplayLabel(),
                        self.datetimeTagLocation, 
                        cv2.FONT_HERSHEY_SIMPLEX, 
                        1,
                        self.datetimeTagColour,
                        2,
                        cv2.LINE_AA)

        # Tag motion indicator        
        if isMotion:
            cv2.putText(inputImg,"Motion Detected!",
                            self.motionTagLocation, 
                            cv2.FONT_HERSHEY_SIMPLEX, 
                            1,
                            self.motionTagColour,
                            2,
                            cv2.LINE_AA)            

    def displayFrame(self, img):
        img_height, img_width, img_colors = img.shape

        scale_w = float(self.window_width) / float(img_width)
        scale_h = float(self.window_height) / float(img_height)
        scale = min([scale_w, scale_h])

        if scale == 0:
            scale = 1
        
        img = cv2.resize(img, None, fx=scale, fy=scale, interpolation = cv2.INTER_CUBIC)
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        height, width, bpc = img.shape
        bpl = bpc * width
        image = QtGui.QImage(img.data, width, height, bpl, QtGui.QImage.Format_RGB888)
        pix = QtGui.QPixmap(image)
        self.live_display.setPixmap(pix)

    # Live Mode
    def update_frame(self):
        if not q.empty():

            # UI thingy
            self.recordButton.setEnabled(True)

            # grab frame from video thread
            try:
                frame = q.get()
                img = frame["img"]
            except:
                print("error obtaining images")
            else:
                # detect motion
                if self.recordOnMotion:
                    # detect motion
                    motionImg = img.copy()
                    self.isMoving = self.motiondetect.detectmotion(motionImg)
                else:
                    self.isMoving = False

                # detect presence
                if self.recordOnPresence:
                    # detect objects and indicate on display
                    img, self.isDetected = self.detector.process_image(img)
                else:
                    self.isDetected = False

                if self.sendOnActivity:
                    if self.isMoving or self.isDetected:
                        self.emailSendTracker(True)
                    else:
                        self.emailSendTracker(False)


                # Tag the frame with indications
                self.drawOnFrame(img,self.isMoving)

                if self.record.getRecordingStatus():
                    self.recordTriggerFunc(img)

                # show frame with annotation
                self.displayFrame(img)


    def closeEvent(self, event):
        global cam_running
        cam_running = False
        self.record.killRecorder()


def main():
    capture_thread = threading.Thread(target=grab, args = (CAM_INDEX, q, CAM_WIDTH, CAM_HEIGHT, CAM_FPS))
    capture_thread.start()

    app = QtWidgets.QApplication(sys.argv)
    w = MyWindowClass(None)
    w.setWindowTitle(WINDOW_TITLE)
    w.show()
    app.exec_()

main()

# Title # Cam Params # (record everything mode) This parameter determines the intervals of recording # in seconds # (smart recording mode) This parameter determines how many more frames to save after inactivity # in frame counts # Threading variables # load UI # parallel threaded camera feed # obtain dim of elements # Livefeed tab: # Recorder object # Detector object # Motion detector object # email alert module # Disable user interface # simple check to evaluate input validity # If successfully logged in # authentication failed # initialize # send out first email here # invoke timeout sequence (2 mins of inactivity, send out last email) # readjust ui according to window size # MainWindow.textEdit.setGeometry(QtCore.QRect(30, 80, 341, 441)) # Adjust tab widget size # **** Set all elements relative to tabWidget_relativeSizeRatio **** # set triggerGroup Pos: # set recordButton Pos: # set filePath Pos: # finally set the display size # return filepath where video is saved # stop recording # record on presence only # estimate 2 sec of detect nothing #reinitalize # Record everything in interval of 2 minutes # Tag date # Tag motion indicator # Live Mode # UI thingy # grab frame from video thread # detect motion # detect motion # detect presence # detect objects and indicate on display # Tag the frame with indications # show frame with annotation