# main_app.py

import tkinter as tk
from tkinter import ttk, messagebox
from datetime import datetime, timedelta
import threading
import subprocess
import time
import os
import cv2
from PIL import Image, ImageTk

TEST_MODE = True

class TimelapseApp:
    def __init__(self, root):
        self.root = root
        self.root.title("Raspberry Pi Timelapse")
        self.root.geometry("480x700")

        self.preview_running = False
        self.capture_running = False
        self.capture_paused = False

        self.calculation_mode = tk.StringVar(value="dur_int")

        self._build_ui()
        self._set_defaults()
        self._bind_live_updates()
        self._update_derived_values()
        self._update_entry_states()

    def _build_ui(self):
        self.inputs = {}
        labels = ["Duration (min)", "Interval (sec)", "Frames", "FPS"]
        self.vars = {label: tk.StringVar() for label in labels}

        for i, label in enumerate(labels):
            ttk.Label(self.root, text=label).grid(row=i, column=0, sticky='w')
            entry = ttk.Entry(self.root, width=15, textvariable=self.vars[label])
            entry.grid(row=i, column=1)
            self.inputs[label] = entry

        ttk.Label(self.root, text="Calculate from:").grid(row=0, column=2, sticky='w')
        ttk.Radiobutton(self.root, text="Duration + Interval", variable=self.calculation_mode, value="dur_int", command=self._on_mode_change).grid(row=1, column=2, sticky='w')
        ttk.Radiobutton(self.root, text="Interval + Frames", variable=self.calculation_mode, value="int_frames", command=self._on_mode_change).grid(row=2, column=2, sticky='w')
        ttk.Radiobutton(self.root, text="Duration + Frames", variable=self.calculation_mode, value="dur_frames", command=self._on_mode_change).grid(row=3, column=2, sticky='w')

        self.schedule_var = tk.BooleanVar()
        self.schedule_check = ttk.Checkbutton(self.root, text="Schedule start at:", variable=self.schedule_var)
        self.schedule_check.grid(row=4, column=0, sticky='w')

        self.start_time_entry = ttk.Entry(self.root, width=15)
        self.start_time_entry.grid(row=4, column=1)

        self.summary_label = ttk.Label(self.root, text="")
        self.summary_label.grid(row=5, column=0, columnspan=3, pady=5)

        ttk.Separator(self.root, orient='horizontal').grid(row=6, columnspan=3, sticky='ew', pady=5)

        ttk.Button(self.root, text="Start Preview", command=self.start_preview, width=15).grid(row=7, column=0, padx=10, pady=5, ipadx=10, ipady=5)
        ttk.Button(self.root, text="Stop Preview", command=self.stop_preview, width=15).grid(row=7, column=1, padx=10, pady=5, ipadx=10, ipady=5)

        ttk.Button(self.root, text="Start Capture", command=self.start_capture, width=15).grid(row=8, column=0, padx=10, pady=5, ipadx=10, ipady=5)
        ttk.Button(self.root, text="Stop Capture", command=self.stop_capture, width=15).grid(row=8, column=1, padx=10, pady=5, ipadx=10, ipady=5)

        ttk.Button(self.root, text="Pause", command=self.pause_capture, width=15).grid(row=9, column=0, padx=10, pady=5, ipadx=10, ipady=5)
        ttk.Button(self.root, text="Resume", command=self.resume_capture, width=15).grid(row=9, column=1, padx=10, pady=5, ipadx=10, ipady=5)

        self.status_label = ttk.Label(self.root, text="Status: Idle")
        self.status_label.grid(row=10, column=0, columnspan=3, pady=5)

        self.preview_label = tk.Label(self.root)
        self.preview_label.grid(row=11, column=0, columnspan=3, pady=5)

    def _set_defaults(self):
        self.vars["Duration (min)"].set("60")
        self.vars["Interval (sec)"].set("5")
        self.vars["FPS"].set("30")

    def _bind_live_updates(self):
        for key in self.vars:
            self.vars[key].trace_add('write', lambda *args: self._update_derived_values())
        self.calculation_mode.trace_add('write', lambda *args: self._update_derived_values())

    def _on_mode_change(self):
        self._update_entry_states()
        self._update_derived_values()

    def _update_entry_states(self):
        mode = self.calculation_mode.get()
        self.inputs["Duration (min)"].config(state='normal')
        self.inputs["Interval (sec)"].config(state='normal')
        self.inputs["Frames"].config(state='normal')

        if mode == "dur_int":
            self.inputs["Frames"].config(state='disabled')
        elif mode == "int_frames":
            self.inputs["Duration (min)"].config(state='disabled')
        elif mode == "dur_frames":
            self.inputs["Interval (sec)"].config(state='disabled')

    def _update_derived_values(self):
        try:
            duration = int(self.vars["Duration (min)"].get())
        except:
            duration = 0
        try:
            interval = int(self.vars["Interval (sec)"].get())
        except:
            interval = 0
        try:
            frames = int(self.vars["Frames"].get())
        except:
            frames = 0
        try:
            fps = int(self.vars["FPS"].get())
        except:
            fps = 30

        mode = self.calculation_mode.get()

        if mode == "dur_int" and interval > 0:
            frames = int((duration * 60) / interval)
            self.vars["Frames"].set(str(frames))
        elif mode == "int_frames" and frames > 0:
            duration = int((frames * interval) / 60)
            self.vars["Duration (min)"].set(str(duration))
        elif mode == "dur_frames" and frames > 0:
            interval = int((duration * 60) / frames)
            self.vars["Interval (sec)"].set(str(interval))

        total_video_sec = frames / fps if fps else 0
        summary = f"Total duration: {duration} min | Frames: {frames} | Output video: {total_video_sec:.1f}s"
        self.summary_label.config(text=summary)

    def start_preview(self):
        if not self.preview_running:
            self.status_label.config(text="Status: Preview running")
            if TEST_MODE:
                self.preview_running = True
                self._start_webcam_preview()
            else:
                self.preview_process = subprocess.Popen(["/home/pi/preview.sh"])
                self.preview_running = True

    def stop_preview(self):
        if self.preview_running:
            if TEST_MODE:
                self.preview_running = False
                if hasattr(self, 'video_capture'):
                    self.video_capture.release()
                self.preview_label.config(image='')
            else:
                self.preview_process.terminate()
            self.status_label.config(text="Status: Preview stopped")
            self.preview_running = False

    def _start_webcam_preview(self):
        self.video_capture = cv2.VideoCapture(0)
        self._update_preview_frame()

    def _update_preview_frame(self):
        if self.preview_running and self.video_capture.isOpened():
            ret, frame = self.video_capture.read()
            if ret:
                frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                frame = cv2.resize(frame, (320, 240))
                image = Image.fromarray(frame)
                photo = ImageTk.PhotoImage(image=image)
                self.preview_label.config(image=photo)
                self.preview_label.image = photo
            self.root.after(100, self._update_preview_frame)

    def stop_capture(self):
        if self.capture_running:
            self.capture_running = False
            self.capture_paused = False
            self.status_label.config(text="Status: Capture stopped")

    def pause_capture(self):
        if self.capture_running:
            self.capture_paused = True
            self.status_label.config(text="Status: Paused")

    def resume_capture(self):
        if self.capture_running and self.capture_paused:
            self.capture_paused = False
            self.status_label.config(text="Status: Resumed")

if __name__ == '__main__':
    root = tk.Tk()
    app = TimelapseApp(root)
    root.mainloop()
