import tkinter as tk
from tkinter import ttk, messagebox
import os
import sys
import builtins
from pathlib import Path

def get_base_path():
    """Get the base path for the application, works both in development and when bundled"""
    if getattr(sys, 'frozen', False):
        # If the application is run as a bundle
        return sys._MEIPASS
    else:
        # If the application is run from a Python interpreter
        return os.path.dirname(os.path.abspath(__file__))

# Configure paths relative to the application
base_path = get_base_path()
tools_path = os.path.join(base_path, 'steamvr', 'tools', 'bin', 'win64')

# Set paths for steamvr module
builtins.valve_tools_path = tools_path
builtins.steam_vr_path = tools_path  # We'll use our bundled tools instead of relying on Steam installation

from steamvr.lighthouse_console import LighthouseConsole
import threading
import time

class ControllerPairingGUI:
    # Controller identifier constants
    RIGHT_CONTROLLER_PREFIX = "DYX"
    LEFT_CONTROLLER_PREFIX = "RYB"
    
    def __init__(self, root):
        self.root = root
        self.root.title("VR Controller Pairing")
        self.root.geometry("400x300")
        
        # Create main frame
        main_frame = ttk.Frame(root, padding="10")
        main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
        
        # Status label
        self.status_label = ttk.Label(main_frame, text="Status: Ready")
        self.status_label.grid(row=0, column=0, columnspan=2, pady=10)
        
        # Device list
        self.device_list = tk.Listbox(main_frame, height=3, width=40)
        self.device_list.grid(row=1, column=0, columnspan=2, pady=10)
        
        # Refresh button
        refresh_btn = ttk.Button(main_frame, text="Refresh Devices", command=self.refresh_devices)
        refresh_btn.grid(row=2, column=0, columnspan=2, pady=5)
        
        # Pairing buttons frame
        pairing_frame = ttk.LabelFrame(main_frame, text="Pair Controllers", padding="5")
        pairing_frame.grid(row=3, column=0, columnspan=2, pady=10, sticky=(tk.W, tk.E))
        
        # Left controller button
        left_btn = ttk.Button(pairing_frame, text="Pair Left Radio", command=lambda: self.pair_controller("left"))
        left_btn.grid(row=0, column=0, padx=5)
        
        # Right controller button
        right_btn = ttk.Button(pairing_frame, text="Pair Right Radio", command=lambda: self.pair_controller("right"))
        right_btn.grid(row=0, column=1, padx=5)
        
        self.console = None
        self.refresh_devices()
    
    def refresh_devices(self):
        """Refresh the list of available devices"""
        try:
            if self.console:
                self.console.close()
            self.console = LighthouseConsole.create()
            self.console.open()
            
            devices = self.console.list_devices()
            self.device_list.delete(0, tk.END)
            # Filter out headset devices (LHR) and only show controllers
            for device in devices:
                if self.RIGHT_CONTROLLER_PREFIX in device or self.LEFT_CONTROLLER_PREFIX in device:
                    self.device_list.insert(tk.END, device)
            
            self.status_label.config(text="Status: Devices refreshed")
        except Exception as e:
            self.status_label.config(text=f"Status: Error - {str(e)}")
            messagebox.showerror("Error", f"Failed to refresh devices: {str(e)}")
    
    def pair_controller(self, side):
        """Pair a controller based on its side (left/right)"""
        # Find the appropriate controller in the list
        target_prefix = self.RIGHT_CONTROLLER_PREFIX if side == "right" else self.LEFT_CONTROLLER_PREFIX
        device_serial = None
        
        for i in range(self.device_list.size()):
            if target_prefix in self.device_list.get(i):
                device_serial = self.device_list.get(i)
                break
        
        if not device_serial:
            messagebox.showwarning("Warning", f"No {side} controller found in the list")
            return
        
        # Start pairing in a separate thread
        threading.Thread(target=self._pair_device, args=(device_serial, side), daemon=True).start()
    
    def _pair_device(self, device_serial, side):
        """Perform the actual pairing operation"""
        try:
            self.status_label.config(text=f"Status: Pairing {side} controller...")
            self.console.select_device(device_serial)
            self.console.pair()
            self.status_label.config(text=f"Status: Pairing {side} controller...")
        except Exception as e:
            self.status_label.config(text=f"Status: Error - {str(e)}")
            messagebox.showerror("Error", f"Failed to pair controller: {str(e)}")
    
    def __del__(self):
        """Cleanup when the window is closed"""
        if self.console:
            self.console.close()

def main():
    root = tk.Tk()
    app = ControllerPairingGUI(root)
    root.mainloop()

if __name__ == "__main__":
    main() 