#lang racket/gui

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require "Cortex-vision-art.rkt")
(require "Cortex-tacto-art.rkt")
(require "Cortex-olfato-art.rkt")
(require "Red-discriminacion-vision.rkt")
(require "Red-discriminacion-tacto.rkt")
(require "Red-analisis-olfato.rkt")
(require "Cortex-frontal.rkt")
(require "Red-Comparar-anterior.rkt")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define control%
  (class object%
    (init-field
     (cortex_vision 'cortex_vision)
     (cortex_tacto 'cortex_tacto)
     (cortex_olfato 'cortex_olfato)
     (Orden_vision 'discriminacion_visual)
     (Discriminacion_tacto 'discriminacion_tactil)
     (Analisis_olfativo 'analisis_olfativo)
     (automata_frontal  'decision)
     (red-mover-segun-orden-anterior 'comparar_anterior)
     )
    (field
;     (emocion 0)
     (orden_ensayada #f)
     (memoria '())
     )
    (define-struct recuerdo
      (visto
       tocado
       olfateado
       (emocion-orden #:mutable);(cons orden emocion)
       iteracion)
      #:transparent
      )
    (define comparar
      (lambda (item1 item2)
        (let ((vista1 (recuerdo-visto item1))
              (tacto1 (recuerdo-tocado item1))
              (olfato1 (recuerdo-olfateado item1))
              (vista2 (first item2))
              (tacto2 (second item2))
              (olfato2 (third item2))
              )
          (and
           (equal? vista1 vista2)
           (equal? tacto1 tacto2)
           (equal? olfato1 olfato2)
           )
          )
        ))
    (define sensor_energia
      (lambda (energia)
        (cond
          ((>= energia 100) 0)
          ((and (< energia 100) (> energia 0)) 1)
          ((and (<= energia 0) (> energia -200)) 2)
          ((<= energia -200) #f)
          )
        ))
    (define/public proceso!
      (lambda (output_retina output_tactil output_olfativo energia)
        (let*-values 
            (
             [(output_vision)
              (send cortex_vision proceso! output_retina)]
             [(output_tacto)
              (send cortex_tacto proceso! output_tactil)]
             [(output_olfato)
              (send cortex_olfato proceso! output_olfativo)]
             [(orden_visual)
              (send Orden_vision proceso! (take output_vision 3))]
             [(Discriminacion_tactil)
              (send Discriminacion_tacto proceso! output_tacto)]
             [(Analisis_olfato)
              (send Analisis_olfativo proceso! output_olfato)]
             [(orden) 
              (send automata_frontal proceso! orden_visual Discriminacion_tactil Analisis_olfato (sensor_energia energia))]
             )
;Si la orden anterior fue comer y la de ahora es avanzar, avanza a la posición del objeto comido
          (set! orden
                (if (and orden_ensayada (= (car orden) 0))
                    (send red-mover-segun-orden-anterior proceso! (append orden_ensayada orden))
                    orden)
;                (if (and orden_ensayada (= (car orden) 0) (member 1 (cdr orden)))
;                    (cons 0 orden_ensayada) 
;                  orden)
                )
          (set! orden_ensayada (if (and (= (car orden) 1) (member 1 (cdr orden))) (cdr orden) #f))
          (unless (null? memoria)
            (if (comparar (car memoria) (list output_vision output_tacto output_olfato))
                (printf "~nNo se perciben cambios~n")
                (begin
                  (printf "~nSe perciben cambios, luego la acción anterior ha tenido éxito~n")
                  (set-recuerdo-emocion-orden! (car memoria) (cons (car (recuerdo-emocion-orden (car memoria))) 1)) 
                  )
                )
            (printf "Recuerdo: ~a~n" (car memoria))
            )
;            (printf "~nComparados recuerdo y sensaciones: ~a~n" (comparar (car memoria) (list output_vision output_tacto output_olfato))))
          (set! memoria
                (cons
                 (make-recuerdo output_vision output_tacto output_olfato (cons orden 0) (add1 (length memoria)))
                 memoria))
          (printf "Nuevo recuerdo: ~a~n" (car memoria))
          orden
          )
        ))
    (super-new)
    ))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define cerebro (make-object control% cortex_vision cortex_tacto cortex_olfato discriminacion_visual discriminacion_tactil analisis_olfativo automata_decision comparar_anterior));decision))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(provide cerebro)

;;;;;;;;;;;;;;;;;;;
;(require "Objetos-elementales.rkt")
;(require "Receptores-sensitivos.rkt")


;(send retina proceso! (list blanco blanco blanco))
;(send cortex_vision proceso! (send retina proceso! (list blanco blanco blanco)))
;(send sensores_tacto proceso! (list blanco blanco blanco))
;(send cortex_tacto proceso! (send sensores_tacto proceso! (list blanco blanco blanco)))
;(newline)
;(send retina proceso! (list verde verde verde))
;(send cortex_vision proceso! (send retina proceso! (list verde verde verde)))
;(send sensores_tacto proceso! (list verde verde verde))
;(send cortex_tacto proceso! (send sensores_tacto proceso! (list verde verde verde)))
;(newline)
;(send retina proceso! (list azul azul azul))
;(send cortex_vision proceso! (send retina proceso! (list azul azul azul)))
;(send sensores_tacto proceso! (list azul azul azul))
;(send cortex_tacto proceso! (send sensores_tacto proceso! (list azul azul azul)))
;(newline)
;(send retina proceso! (list rojo rojo rojo))
;(send cortex_vision proceso! (send retina proceso! (list rojo rojo rojo)))
;(send sensores_tacto proceso! (list rojo rojo rojo))
;(send cortex_tacto proceso! (send sensores_tacto proceso! (list rojo rojo rojo)))
;(newline)
;(send retina proceso! (list negro negro negro))
;(send cortex_vision proceso! (send retina proceso! (list negro negro negro)))
;(send sensores_tacto proceso! (list negro negro negro))
;(send cortex_tacto proceso! (send sensores_tacto proceso! (list negro negro negro)))

;(newline)
;(send cerebro proceso! (send retina proceso! (list verde verde verde)) (send sensores_tacto proceso! (list verde verde verde)) -10)
;
;(newline)
;(send cerebro proceso! (send retina proceso! (list blanco verde verde)) (send sensores_tacto proceso! (list blanco verde verde)) -10)
;
;(newline)
;(send cerebro proceso! (send retina proceso! (list verde azul verde)) (send sensores_tacto proceso! (list verde azul verde)) -10)