#lang racket/gui

(require (only-in "Objetos.rkt" olor%))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require "Receptores-sensitivos.rkt")
(require "Cerebro.rkt")
(require "Efectores.rkt")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define animat%
  (class object%
    (init-field
     (id 'id)
     (Energia 100)
     (Retina 'retina)
     (Tacto 'tacto)
     (Olfato 'olfato)
     (Efectores 'efectores)
     (control_central 'cerebro)
     (color 'obj_color);(make-object color% 255 0 0 1.0))
     (estado 1)
     )
    (field
     (orientacion 'N)
     (accion 'avanzar)
     (dureza 5)
     (olor (make-object olor% 4 1))
     (obj-temp #f)
     )
    (define/public set-obj-temp
      (lambda (valor)
        (set! obj-temp valor)
        ))
    (define/public get-obj-temp
      (lambda ()
        obj-temp ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    (define/public get-id
      (lambda ()
        id ))
    (define/public get-olor
      (lambda ()
        olor ))
    (define/public get-dureza
      (lambda ()
        dureza ))
    (define/public get-estado
      (lambda ()
        estado))
    ;
    (define/public set-energia
      (lambda (v)
        (set! Energia (- Energia v))
        ))
    ;;
    (define/public exito
      (lambda (arg)
        (send control_central exito! arg)
        ;#t
        ))
    (define/public set-rgb
      (lambda (r v a o)
        (set! color
              (make-object color% r v a o)
              )
        ))
    (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 son-estimulos2
      (lambda (e1 e2 e3 e4 e5 e6 e7 e8 orientacion)
        (cond
          ((eq? orientacion 'N) (values e1 e2 e3 e4 e5 e6 e7 e8))
          ((eq? orientacion 'E) (values e3 e4 e5 e6 e7 e8 e1 e2))
          ((eq? orientacion 'S) (values e5 e6 e7 e8 e1 e2 e3 e4))
          ((eq? orientacion 'O) (values e7 e8 e1 e2 e3 e4 e5 e6))
          )
        ))
    (define/public procesar!
      (lambda (x y lista-8vec-coord lista-8vec-obj lista-8vec-olores)
        (if (<= Energia -200)
            (values 'morir #f (cons x y))
            (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)]
                 [(O1 O2 O3 O4 O5 O6 O7 O8) (son-estimulos2 o1 o2 o3 o4 o5 o6 o7 o8 orientacion)]
                 [(output_retina) (send Retina proceso! (list obj_1 obj_2 obj_3))]
                 [(output_sensores_tacto) (send Tacto proceso! (list obj_1 obj_2 obj_3))]
                 [(output_sensores_olfato) (send Olfato proceso! (list O1 O2 O3 O4 O5 O6 O7 O8))]
                 [(orden_motora) (send control_central proceso! output_retina output_sensores_tacto output_sensores_olfato Energia)]
                 [(accion c_1 c_2) (send Efectores hacer! orden_motora (cons x y) (list v_1 v_2 v_3))]
                 )
              (cond
                ((eq? accion 'avanzar)
                 (set! accion 'avanzar)
                 (set! Energia (- Energia 1))
                 )
                ((eq? accion 'comer)
                 (set! accion 'comer)
                 (set! Energia (+ Energia 5))
                 )
                ((eq? accion 'empujar)
                 (set! accion 'EMPUJAR)
                 (set! Energia (- Energia 3))
                 )
                ((eq? accion 'girar)
                 (set! orientacion c_1)
                 (set! accion 'girar)
                 (set! Energia (- Energia 1))
                 )
                )
              (printf "Orden ~a Acción: ~a hacia ~a. Energía: ~a~n" orden_motora accion orientacion Energia)
              (values accion c_1 c_2)
              )
            )
        ))        
    (super-new)
    ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define A1 (make-object animat% 'A1 50 retina1 tacto1 olfato1 efectores1 cerebro1 (make-object color% 255 0 0 1.0)))
(define A2 (make-object animat% 'A2 50 retina2 tacto2 olfato2 efectores2 cerebro2 (make-object color% 255 0 0 1.0)))

(provide animat% A1 A2)

