import cv2
import numpy as np
import os
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

# Define the folder to monitor
folder_to_monitor = 'C:\\Users\\david\\Desktop\\TESTING\\scans'

# Define the output folder
output_folder = 'C:\\Users\\david\\Desktop\\TESTING\\output'

# Configure Settings


# ThreshHold Settings
thresholdValue = 205
maxValue = 225

# Canny Edge Detection
upper = 50
lower = 150

# Create a class to handle file system events
class ImageHandler(FileSystemEventHandler):
    def on_created(self, event):
        if event.is_directory:
            return

        if event.src_path.endswith(('.jpg', '.png', '.jpeg')):
            print(f"New image detected: {event.src_path}")
            process_image(event.src_path)
            
# Initialize a counter for frame filenames
frame_counter = 1

# Function to process an image
def process_image(image_path):
    # Declare frame_counter as global    
    global frame_counter
    
    # Load the original image
    original_image = cv2.imread(image_path)

    # Rotate the original image 180 degrees
    rotated_image = cv2.rotate(original_image, cv2.ROTATE_180)

    # Convert to grayscale
    grey = cv2.cvtColor(rotated_image, cv2.COLOR_BGR2GRAY)

    # Use threshold to convert image to binary
    ret, thresh1 = cv2.threshold(grey, thresholdValue, maxValue, cv2.THRESH_BINARY) # 213

    # Apply morphological operations to remove specs or dirt/noise from the sprocket holes
    kernel = np.ones((8, 8), np.uint8)
    closing = cv2.morphologyEx(thresh1, cv2.MORPH_CLOSE, kernel, iterations=2)

    # Edge Detection for detecting contours
    edge = cv2.Canny(closing, upper, lower, apertureSize=7, L2gradient=True)

    # Finding Contours
    cnts, _ = cv2.findContours(edge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

    cnts = sorted(cnts, key=lambda x: cv2.boundingRect(x)[0])

    # Create a list to store the cropped ROIs
    cropped_rotated_rois = []

    for c in cnts:
        x, y, w, h = cv2.boundingRect(c)

        if h > 200 and w > 20:
            # Adjust the coordinates to create a larger bounding box
            x -= -50  # Move the left edge 10 pixels to the left
            y -= 10  # Move the top edge 10 pixels up
            w += 600  # Increase the width by 20 pixels
            h += 1050  # Increase the height by 20 pixels

            # Crop the ROI from the original image
            roi = rotated_image[y:y+h, x:x+w]

            # Rotate the cropped ROI (90 degrees clockwise)
            rotated_roi = cv2.rotate(roi, cv2.ROTATE_90_CLOCKWISE)

            # Flip the rotated ROI vertically
            flipped_roi = cv2.flip(rotated_roi, 1)

            # Append the rotated and flipped ROI to the list
            cropped_rotated_rois.append(flipped_roi)

    # Discard the last ROI if there are more than one
    if len(cropped_rotated_rois) > 1:
        cropped_rotated_rois.pop()

    # Save each cropped ROI to the output folder
    for idx, roi in enumerate(cropped_rotated_rois):
        output_filename = f"frame{frame_counter:06}.jpg"
        output_path = os.path.join(output_folder, output_filename)
        cv2.imwrite(output_path, roi)
        print(f"Processed image saved: {output_path}")
        
        # Increment the frame counter
        frame_counter += 1

# Set up the watchdog observer
event_handler = ImageHandler()
observer = Observer()
observer.schedule(event_handler, folder_to_monitor, recursive=False)
observer.start()

print(f"Monitoring folder: {folder_to_monitor}")
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    observer.stop()

observer.join()

# Call the process_image function for each image
for image_filename in image_filenames:
    image_path = os.path.join(input_folder, image_filename)
    process_image(image_path)