module Alimento

    # Esta clase representa el nodo de una lista. 
    Nodo = Struct.new(:valor, :siguiente, :anterior)
    
    # Esta clase es la definición de una lista doblemente enlazada.
    class Lista
    
        include Enumerable
        attr_reader :head, :tail
    
        # Inicia la lista (vacía). 
        def initialize
            @head = nil
            @tail = nil
        end
        
        # Permite insertar un valor en la lista por delante. 
        def insertar_head(valor)
            
            nodo = Nodo.new(valor,nil,nil)
            
            if (@head == nil)
                @head = nodo
                @tail = nodo
            else
                @head.anterior = nodo
                nodo.siguiente = @head
                @head = nodo
            end
        end
        
        # Permite insertar un valor en la lista por detrás. 
        def insertar_tail(valor)
            
            nodo = Nodo.new(valor,nil,nil)
            
            if (@tail == nil)
                @tail = nodo
                @head = nodo
            else
                @tail.siguiente = nodo
                nodo.anterior = @tail
                @tail = nodo
            end
        end
        
        # Elimina el primer elemento de la lista. 
        def extraer_head
            @head = @head.siguiente
        end
        
        # Elimina el último elemento de la lista. 
        def extraer_tail
            @tail = @tail.anterior
        end
        
        # Se incluye el metodo del mixin Enumerable. 
        # Iteración sobre los elementos de la lista desde el principio hasta el final.
        def each
            iterador = @head
    		while iterador != nil
    		    yield iterador.valor
    			iterador = iterador.siguiente
    		end
        end
    
    end
end