import bpy
import socket
import struct

class UDP_Cherry_Inspector(bpy.types.Operator):
    bl_idname = "wm.udp_cherry_inspector"
    bl_label = "UDP Cherry Inspector Receiver"
    _timer = None
    _sock = None

    def modal(self, context, event):
        if event.type == 'TIMER':
            try:
                # Recibimos el paquete de 28 bytes (7 floats de 4 bytes cada uno)
                data, addr = self._sock.recvfrom(28)
                v = struct.unpack('f' * 7, data)
                
                # 1. MOVER EL OBJETIVO (Donde están las guindas)
                # v[0,1,2] -> X, Y, Z globales del punto de interés
                foco = bpy.data.objects.get("Objetivo_Camara")
                if foco:
                    foco.location = (v[0], v[1], v[2])
                
                # 2. MOVER LA CÁMARA PRINCIPAL (Frente al árbol)
                # v[3,4,5] -> X, Y, Z globales de la posición de la cámara
                cam = bpy.data.objects.get("Camera6Ejes")
                if cam:
                    cam.location = (v[3], v[4], v[5])
                
                # 3. AJUSTAR ZOOM DE LA CÁMARA DETALLE
                # v[6] -> Valor del lente (Focal Length) en mm
                c_zoom = bpy.data.objects.get("CameraZoom")
                if c_zoom and c_zoom.type == 'CAMERA':
                    c_zoom.data.lens = v[6]
                    
            except:
                pass # No hay datos nuevos en este tick del timer
        
        if event.type == 'ESC':
            return self.cancel(context)
            
        return {'PASS_THROUGH'}

    def execute(self, context):
        # Configuración del socket UDP
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self._sock.bind(("127.0.0.1", 5005))
        self._sock.setblocking(0)
        
        # Crear un temporizador para que Blender revise el socket cada 0.01 segundos
        self._timer = context.window_manager.event_timer_add(0.01, window=context.window)
        context.window_manager.modal_handler_add(self)
        
        print("SISTEMA ACTIVO: Esperando datos de VS Code en puerto 5005...")
        return {'RUNNING_MODAL'}

    def cancel(self, context):
        context.window_manager.event_timer_remove(self._timer)
        self._sock.close()
        print("Sistema detenido.")
        return {'CANCELLED'}

# Registro del operador
if __name__ == "__main__":
    # Si ya estaba registrado, lo quitamos para evitar conflictos
    if hasattr(bpy.types, "UDP_Cherry_Inspector"):
        bpy.utils.unregister_class(UDP_Cherry_Inspector)
        
    bpy.utils.register_class(UDP_Cherry_Inspector)
 	bpy.ops.wm.udp_cherry_inspector()

