#lang racket/gui

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require "Retina.rkt")
(require "Efectores.rkt")
(require "Cerebro.rkt")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define animat%
  (class object%
    (init-field
     (retina 'retina)
     (Efectores 'Efectores)
     (control_central 'cerebro)
     (estado 1)
     )
    (field
     (color (make-object color% 255 0 0 1.0))
     (orientacion 'N)
     (accion 'avanzar)
     )
    (define/public get-estado
      (lambda ()
        estado))
    (define/public get-rgb
      (lambda ()
        (let ((r (send color red))
              (g (send color green))
              (b (send color blue))
              (o (send color alpha))
              )
          (list r g b o)
          )
        ))
    (define/public get-color
      (lambda ()
        color ))
    (define es-de-color?
      (lambda (rgb-obj esquema)
        (equal? rgb-obj esquema)
        ))
    (define/public get-orientacion
      (lambda ()
        orientacion ))
    (define/public get-accion
      (lambda ()
        accion ))
    (define son-estimulos
      (lambda (e1 e2 e3 e4 e5 e6 e7 e8 orientacion)
        (cond
          ((eq? orientacion 'N) (values e1 e2 e3))
          ((eq? orientacion 'E) (values e3 e4 e5))
          ((eq? orientacion 'S) (values e5 e6 e7))
          ((eq? orientacion 'O) (values e7 e8 e1))
          )
        ))
    (define/public procesar!
      (lambda (x y lista-8vec-coord lista-8vec-obj)
        (let*-values
            ([(v1 v2 v3 v4 v5 v6 v7 v8) (apply values lista-8vec-coord)]
             [(o1 o2 o3 o4 o5 o6 o7 o8) (apply values lista-8vec-obj)]
             [(v_1 v_2 v_3) (son-estimulos v1 v2 v3 v4 v5 v6 v7 v8 orientacion)]
             [(obj_1 obj_2 obj_3) (son-estimulos o1 o2 o3 o4 o5 o6 o7 o8 orientacion)]
             [(output_retina) (send retina proceso! (list obj_1 obj_2 obj_3))]
             [(orden_motora) (send control_central proceso! output_retina)]
             [(bool c_1 c_2)
              (send Efectores hacer! orden_motora (cons x y) (list v_1 v_2 v_3))]
             )
          (printf "Retina ~a Orden ~a~n" output_retina orden_motora)
          (cond
            ((eq? bool 'avanzar)
             (set! accion 'avanzar)
             (printf "Acción: ~a hacia ~a~n" accion orientacion)
             )
            ((eq? bool 'girar)
             (set! orientacion c_1)
             (set! accion 'Girar)
             (printf "Acción: ~a hacia ~a~n" accion orientacion)
             )
            )
          (values bool c_1 c_2)
          )
        ))     
    (super-new)
    ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define A1 (make-object animat% retina efectores cerebro))

(provide animat% A1)