# encoding: utf-8

# To change this license header, choose License Headers in Project Properties.
# To change this template file, choose Tools | Templates
# and open the template in the editor.



module NapakalakiModel

require "Singleton"

require_relative 'monster'
require_relative 'treasure'
require_relative 'treasure_kind'
require_relative 'cultist'
require_relative 'bad_consequence'
require_relative 'numeric_bad_consequence'
require_relative 'specific_bad_consequence'
require_relative 'death_bad_consequence'
  
class CardDealer
  
  include Singleton

  
  # Constructor.
  def initialize
    
    @usedMonsters = Array.new
    @unusedMonsters = Array.new
    @usedTreasures = Array.new
    @unusedTreasures = Array.new
    @unusedCultists = Array.new
    
  end
  
   
  #******************************************************
  # Métodos privados.
  #******************************************************
  private
    
    #******************************************************
    # Inicializa el mazo de cartas de Tesoros (unusedTreasures) con 
    # todas las cartas de tesoros proporcionadas en el documento 
    # de cartas de tesoros.
    def initTreasureCardDeck
        
      #***********************************************/
      # !Si mi amo!
      @unusedTreasures << (Treasure.new("¡Si mi amo!",4,TreasureKind::HELMET));
        
      # ***********************************************/
      # Botas de investigación       
      @unusedTreasures << (Treasure.new("Botas de investigacion.",3,TreasureKind::SHOES));
        
      # ***********************************************/
      # Capucha de Cthulhu       
      @unusedTreasures << (Treasure.new("Capucha de Cthulhu",3,TreasureKind::HELMET));
       
      #***********************************************/
      # A prueba de balas        
      @unusedTreasures << (Treasure.new("A prueba de balas.",2,TreasureKind::ARMOR));
        
      # ***********************************************/
      # Botas de lluvia ácida        
      @unusedTreasures << (Treasure.new("Botas de lluvia acida.",1,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Casco minero          
      @unusedTreasures << (Treasure.new("Casco minero.",2,TreasureKind::HELMET));
        
      #***********************************************/
      # Ametralladora Thompson      
      @unusedTreasures << (Treasure.new("Ametralladora Thompson.",4,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Camiseta de la UGR      
      @unusedTreasures << (Treasure.new("Camiseta de la UGR.",1,TreasureKind::ARMOR));
        
      #***********************************************/
      # Clavo de rail ferroviario 
      @unusedTreasures << (Treasure.new("Clavo de rail ferroviario.",3,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Cuchillo de sushi arcano       
      @unusedTreasures << (Treasure.new("Cuchillo de sushi arcano.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Fez alopodo       
      @unusedTreasures << (Treasure.new("Fez alopodo.",3, TreasureKind::HELMET));
        
      #***********************************************/
      # Hacha prehistorica       
      @unusedTreasures << (Treasure.new("Hacha prehistorica.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # El aparato del Pr.Tesla      
      @unusedTreasures << (Treasure.new("El aparato del Pr.Tesla.",4, TreasureKind::ARMOR));
        
      #***********************************************/
      # Gaita   
      @unusedTreasures << (Treasure.new("Gaita.",4,TreasureKind::BOTHHANDS));
          
      #***********************************************/
      # Insecticida 
      @unusedTreasures << (Treasure.new("Insecticida.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Escopeta de 3 cañones      
      @unusedTreasures << (Treasure.new("Escopeta de 3 cañones.",4,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Garabato mistico       
      @unusedTreasures << (Treasure.new("Garabato mistico.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # La rebeca metalica      
      @unusedTreasures << (Treasure.new("La rebeca metalica.",2,TreasureKind::ARMOR));
       
      #***********************************************/
      # Lanzallamas        
      @unusedTreasures << (Treasure.new("Lanzallamas.",4,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Necro-comicon       
      @unusedTreasures << (Treasure.new("Necro-comicon.",1,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Necronomicon       
      @unusedTreasures << (Treasure.new("Necronomicon.",5,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Linterna a 2 manos   
      @unusedTreasures << (Treasure.new("Linterna a 2 manos.",3,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Necro-gnomicon      
      @unusedTreasures << (Treasure.new("Necro-gnomicon.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Necrotelecom   
      @unusedTreasures << (Treasure.new("Necrotelecom.",2,TreasureKind::HELMET));
        
      #***********************************************/
      # Mazo de los antiguos  
      @unusedTreasures << (Treasure.new("Mazo de los antiguos.",3,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Necro-playboycon        
      @unusedTreasures << (Treasure.new("Necro-playboycon.",3,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Porra preternatural     
      @unusedTreasures << (Treasure.new("Porra preternatural.",2,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Shogulador     
      @unusedTreasures << (Treasure.new("Shogulador.",1,TreasureKind::BOTHHANDS));
        
      #***********************************************/
      # Varita de atizamiento   
      @unusedTreasures << (Treasure.new("Varita de atizamiento.",3,TreasureKind::ONEHAND));
        
      #***********************************************/
      # Tentaculo de pega  
      @unusedTreasures << (Treasure.new("Tentaculo de pega.",2,TreasureKind::HELMET));
        
      #***********************************************/
      # Zapato deja-amigos 
      @unusedTreasures << (Treasure.new("Zapato deja-amigos.",1,TreasureKind::SHOES));
        
             
    end
    
    #******************************************************
    # Inicializa el mazo de cartas de monstruos (unusedMonsters), 
    # con todas las cartas de monstruos proporcionadas en el documento 
    # de cartas de monstruos.
    def initMonsterCardDeck
            
      #******************************************************/
      # El rey de la rosa.
      prize = Prize.new(4,2)

      badConsequence =
      NumericBadConsequence.new("Pierdes 5 niveles y 3
      tesoros visibles.",5 , 3, 0)

      @unusedMonsters << Monster.newNormalMonster('El rey de rosa',13,prize,badConsequence)


      #******************************************************/
      # Ángeles de la noche ibicenca.
      prize = Prize.new(4,1)

      badConsequence = SpecificBadConsequence.new('Te
      atrapan para llevarte de fiesta y te dejan caer en mitad del vuelo. Descarta 1
      mano visible y 1 mano oculta.', 0,[TreasureKind::ONEHAND], [TreasureKind::ONEHAND])

      @unusedMonsters << Monster.newNormalMonster('Angeles de la noche ibicenca', 14, prize,
      badConsequence)

      #******************************************************/
      # 3 Byakhees de bonanza
      prize = Prize.new(2,1)

      badConsequence = SpecificBadConsequence.new('Pierdes tu armadura
      visible y otra oculta.', 0,[TreasureKind::ARMOR], [TreasureKind::ARMOR])

      @unusedMonsters << Monster.newNormalMonster('3 Byakhees de bonanza',8,prize,badConsequence)

      #******************************************************/
      # Chibithulhu
      prize = Prize.new(1,1)

      badConsequence = SpecificBadConsequence.new('Embobados con el lindo
      primigenio te descartas de tu casco visible.', 0,[TreasureKind::HELMET], Array.new)

      @unusedMonsters << Monster.newNormalMonster('Chibithulhu',2,prize,badConsequence)

      #******************************************************/
      # El sopor de Dunwich
      prize = Prize.new(1,1)

      badConsequence = SpecificBadConsequence.new('El primordial bostezo
      contagioso. Pierdes el calzado visible.', 0,[TreasureKind::SHOES], Array.new)

      @unusedMonsters << Monster.newNormalMonster('El sopor de Dunwich',2,prize,badConsequence)

      #******************************************************/
      # El gorrón en el umbral.
      prize = Prize.new(3,1)

      badConsequence =
      NumericBadConsequence.new("Pierdes todos tus tesoros
      visibles.",0 , BadConsequence.getMaxTreasures, 0)

      @unusedMonsters << Monster.newNormalMonster('El gorron en el umbral',10,prize,badConsequence)

      #******************************************************/
      # H.P. Munchcraft
      prize = Prize.new(2,1)

      badConsequence = SpecificBadConsequence.new('Pierdes la armadura
      visible.', 0,[TreasureKind::ARMOR], Array.new)

      @unusedMonsters << Monster.newNormalMonster('H.P. Munchcraft', 6, prize,badConsequence)

      #******************************************************/
      # Bichgooth
      prize = Prize.new(1,1)

      badConsequence = SpecificBadConsequence.new('Sientes bichos bajo la
      ropa. Descarta la armadura visible.', 0,[TreasureKind::ARMOR], Array.new)

      @unusedMonsters << Monster.newNormalMonster('Bichgooth', 2, prize,badConsequence)

      #******************************************************/
      # La que redacta en las tinieblas.
      prize = Prize.new(1,1)

      badConsequence =
      NumericBadConsequence.new("Toses los pulmones y
      pierdes 2 niveles.", 2, 0, 0)

      @unusedMonsters << Monster.newNormalMonster('La que redacta en las tinieblas',2,prize,badConsequence)

      #******************************************************/
      # Los hondos.
      prize = Prize.new(2,1)

      badConsequence =
      DeathBadConsequence.new("Estos monstruos resultan
      bastante superficiales y te aburren mortalmente. Estas muerto.")

      @unusedMonsters << Monster.newNormalMonster('Los hondos',8,prize,badConsequence)

      #******************************************************/
      # Semillas Cthulhu
      prize = Prize.new(2,1)

      badConsequence = NumericBadConsequence.new('Pierdes 2 niveles y 2
      tesoros ocultos.',2 , 0, 2)

      @unusedMonsters << Monster.newNormalMonster('Semillas Cthulhu',4,prize,badConsequence)

      #******************************************************/
      # Dameargo
      prize = Prize.new(2,1)

      badConsequence = SpecificBadConsequence.new('Te
      intentas escaquear. Pierdes una mano visible.', 0,[TreasureKind::ONEHAND],Array.new)

      @unusedMonsters<< Monster.newNormalMonster('Dameargo', 1, prize, badConsequence)

      #******************************************************/
      # Pollipolipo volante
      prize = Prize.new(1,1)

      badConsequence = NumericBadConsequence.new('Da mucho asquito. Pierdes tres 
      niveles.',3 , 0, 0)

      @unusedMonsters << Monster.newNormalMonster('Pollipolipo volante',3,prize,badConsequence)

      #******************************************************/
      # Yskhtihyssg-Goth
      prize = Prize.new(3,1)

      badConsequence = DeathBadConsequence.new('No le hace gracia que
      pronuncien mal su nombre. Estas muerto.')

      @unusedMonsters << Monster.newNormalMonster('Dameargo', 12, prize, badConsequence)


      #******************************************************/
      # Familia feliz
      prize = Prize.new(4,1)

      badConsequence = DeathBadConsequence.new('La familia te atrapa.
      Estas muerto.')

      @unusedMonsters << Monster.newNormalMonster('Familia feliz', 1, prize, badConsequence)


      #******************************************************/
      # Roboggoth
      prize = Prize.new(2,1)

      badConsequence = SpecificBadConsequence.new('La quinta directiva
      primaria te obliga a perder 2 niveles y un tesoro de 2 manos visible',
      2,[TreasureKind::BOTHHANDS],Array.new)

      @unusedMonsters << Monster.newNormalMonster('Roboggoth', 8, prize, badConsequence)


      #******************************************************/
      # El Lenguas
      prize = Prize.new(1,1)

      badConsequence = NumericBadConsequence.new('Menudo susto te llevas.
      Pierdes 2 niveles y 5 tesoros visibles.',2 , 5, 0)

      @unusedMonsters << Monster.newNormalMonster('El Lenguas',20,prize,badConsequence)   

      #******************************************************/
      # El espía
      prize = Prize.new(1,1)

      badConsequence = SpecificBadConsequence.new('Te asusta en la noche.
      Pierdes un casco visible.', 0,[TreasureKind::HELMET],Array.new)

      @unusedMonsters << Monster.newNormalMonster('El espia', 5, prize, badConsequence)

      #******************************************************/      
      # Bicéfalo
      prize = Prize.new(1,1)

      badConsequence = SpecificBadConsequence.new('Te faltan manos para
      tanta cabeza. Pierdes 3 niveles y tus tesoros visibles de las manos.',
      3,[TreasureKind::BOTHHANDS,TreasureKind::ONEHAND, TreasureKind::ONEHAND],Array.new)

      @unusedMonsters << Monster.newNormalMonster('Bicefalo', 20, prize, badConsequence)

      
      #******************************************************/
      # A partir de aquí van los monstruos sectarios.
      #******************************************************/
      
      # El mal indecible impronunciable.       
      badConsequence = SpecificBadConsequence.new("Pierdes 1 mano visible.",0,
      [TreasureKind::ONEHAND],Array.new); 
        
      prize = Prize.new(3,1);  
        
      @unusedMonsters << Monster.newCultistMonster("El mal indecible impronunciable", 10, badConsequence, prize, -2);    
      
      #******************************************************/       
      # Testigos oculares.      
      badConsequence = NumericBadConsequence.new("Pierdes tus tesoros " +
      "visibles. Jajaja.." , 0, BadConsequence.getMaxTreasures, 0); 
        
      prize = Prize.new(2,1);  
        
      @unusedMonsters << Monster.newCultistMonster("Testigos oculares", 6, badConsequence, prize, 2);
      
      
      #******************************************************/
      # El gran cthulhu.
      badConsequence = DeathBadConsequence.new("Hoy no es tu día de " +
      "suerte. Mueres..."); 
        
      prize = Prize.new(2,5);
        
      @unusedMonsters << Monster.newCultistMonster("El gran cthulhu", 20, badConsequence, prize, 4);
        
        
      #******************************************************/       
      # Serpiente político.      
      badConsequence = NumericBadConsequence.new("Tu gobierno te recorta " +
      "2 niveles." , 2, 0, 0); 
        
      prize = Prize.new(2,1);  
        
      @unusedMonsters << Monster.newCultistMonster("Serpiente político", 8, badConsequence, prize, -2);
        
           
      #******************************************************/       
      # Felpuggoth.       
      badConsequence = SpecificBadConsequence.new("Pierdes tu casco y tu " +
      "armadura visible. Pierdes tus manos ocultas.",0,
      [TreasureKind::HELMET,TreasureKind::ARMOR],[TreasureKind::BOTHHANDS,TreasureKind::ONEHAND,
                TreasureKind::ONEHAND]); 
        
      prize = Prize.new(1,1);  
        
      @unusedMonsters << Monster.newCultistMonster("Felpuggoth", 2, badConsequence, prize, 5);
        
                
      #******************************************************/       
      # Shoggoth.      
      badConsequence = NumericBadConsequence.new("Pierdes 2 niveles.", 2, 0, 0); 
        
      prize = Prize.new(4,2);  
        
      @unusedMonsters << Monster.newCultistMonster("Shoggoth", 16, badConsequence, prize, -4);
        
        
      #******************************************************/       
      # Lolitagooth.      
      badConsequence = NumericBadConsequence.new("Pintalabios negro. Pierdes 2 niveles.", 2, 0, 0); 
        
      prize = Prize.new(1,1);  
        
      @unusedMonsters << Monster.newCultistMonster("Lolitagooth", 2, badConsequence, prize, 3);
     
    end
    
    #******************************************************
    # Baraja el mazo de cartas de tesoros unusedTreasures.
    def shuffleTreasures
      @unusedTreasures.sort_by { rand }
    end
    
    #******************************************************
    # Baraja el mazo de cartas de monstruos unusedMonsters.
    def shuffleMonsters
      @unusedMonsters.sort_by { rand }
    end
  
  
  #******************************************************
  # Métodos públicos.
  #******************************************************
  public
  def nextTreasure
    
    # Si el mazo de tesoros está vacío.
    if (@unusedTreasures.empty?)
      
      # Pasamos todo del mazo de descartes al mazo de tesoros.
      @usedTreasures.each { |t| 
      
        @unusedTreasures << t
        
      }
      
      # Barajamos mazo de tesoros.
      self.shuffleTreasures
      
      # Vaciamos el mazo de descartes.
      @usedTreasures.clear
      
    end
    
    # Obtenemos el siguiente tesoro del mazo de tesoros.
    t = @unusedTreasures.at(0)
        
    # Lo eliminamos una vez obtenido.
    @unusedTreasures.delete(t);
        
    # Lo añadimos al mazo de descartes.
    @usedTreasures << t
        
    
    return t
    
  end

  #******************************************************
  # Devuelve el siguiente monstruo que hay en el mazo de monstruos
  # unusedMonsters) y lo elimina de él.
  def nextMonster
    
    # Si el mazo de monstruos está vacío.
    if (@unusedMonsters.empty?)
      
      # Pasamos todo del mazo de descartes al mazo de tesoros.
      @usedMonsters.each { |m| 
      
        @unusedMonsters << m
        
      }
      
      # Barajamos mazo de monstruos.
      self.shuffleMonsters
      
      # Vaciamos el mazo de descartes.
      @usedMonsters.clear
      
    end
    
    # Obtenemos el siguiente monstruo del mazo de monstruos.
    m = @unusedMonsters.at(0)
        
    # Lo eliminamos una vez obtenido.
    @unusedMonsters.delete(m);
        
    # Lo añadimos al mazo de descartes.
    @usedMonsters << m
        
    
    return m
    
  end
  
  #******************************************************
  # Introduce en el mazo de descartes de tesoros (usedTreasures) el tesoro t.
  def giveTreasureBack (t)
    @usedTreasures << t
  end
  
  #******************************************************
  # Introduce en el mazo de descartes de monstruos (usedMonsters) al monstruo m.
  def giveMonsterBack (m)
    @usedMonsters << m
  end
  
  #******************************************************
  # Inicia los mazos de cartas.
  def initCards
    initTreasureCardDeck
    initMonsterCardDeck 
    initCultistCardDeck
  end
 
  #******************************************************/
  # Métodos relacionados con los sectarios.
  #******************************************************/
  
  # Inicia el mazo de sectarios.
  def initCultistCardDeck
    
    cultist = Cultist.new("Sectario1",1);
    @unusedCultists << (cultist);
        
    cultist = Cultist.new("Sectario2",2);
    @unusedCultists << (cultist);
        
    cultist = Cultist.new("Sectario3",1);
    @unusedCultists << (cultist);
        
    cultist = Cultist.new("Sectario4",2);
    @unusedCultists << (cultist);
        
    cultist = Cultist.new("Sectario5",1);
    @unusedCultists << (cultist);
                
    cultist = Cultist.new("Sectario6",1);
    @unusedCultists << (cultist); 

  end
  
  #******************************************************/
  # Baraja el mazo de sectarios.
  def shuffleCultists
    @unusedCultists.sort_by { rand }
  end
  
  
  #******************************************************/
  # Devuelve el siguiente sectario que hay en el mazo de monstruos
  #(unusedCultists)
  def nextCultist
    return @unusedCultists.delete_at(0)
  end
  
end


end