import random

class Generators():
  def __init__(self, bot):
    self.bot = bot

  # Returns a list of all letter pairs in the text
  def make_pairs(self, corpus):
    for i in range(len(corpus)-1):
      yield (corpus[i], corpus[i+1])

  # Returns a list of all letter triplets in the text
  def make_triplets(self, corpus):
    for i in range(len(corpus)-2):
      yield (corpus[i], corpus[i+1], corpus[i+2])

  # Generates a random name
  async def name_gen(self, ctx):
    # Makes a list of all names from "names.txt"
    with open("gwendolyn/resources/names.txt", "r", encoding='utf8') as file_pointer:
      names = file_pointer.read()
    corpus = list(names)

    # Makes a list of pairs
    pairs = self.make_pairs(corpus)
    triplets = self.make_triplets(corpus)

    letter_dict = {}

    # Makes a dictionary of all letters that come after all other letters
    for letter_1, letter_2 in pairs:
      if letter_1 in letter_dict:
        letter_dict[letter_1].append(letter_2)
      else:
        letter_dict[letter_1] = [letter_2]

    for letter_1, letter_2, letter_3 in triplets:
      if letter_1+letter_2 in letter_dict:
        letter_dict[letter_1+letter_2].append(letter_3)
      else:
        letter_dict[letter_1+letter_2] = [letter_3]

    # Choses a random first letter
    first_letter = random.choice(corpus)

    # Makes sure the first letter is not something a name can't start with.
    while first_letter.islower() or first_letter == " " or first_letter == "-" or first_letter == "\n":
      first_letter = random.choice(corpus)

    # Starts the name
    chain = [first_letter]

    # Picks second letter
    second_letter = random.choice(letter_dict[chain[-1]])

    while second_letter == "\n":
      second_letter = random.choice(letter_dict[chain[-1]])

    chain.append(second_letter)

    done = False

    # Creates the name one letter at a time
    while not done:
      if random.randint(1,10) > 1:
        try:
          new_letter = random.choice(letter_dict[chain[-2]+chain[-1]])
        except KeyError():
          new_letter = random.choice(letter_dict[chain[-1]])
      else:
        new_letter = random.choice(letter_dict[chain[-1]])
      chain.append(new_letter)
      # Ends name if the name ends
      if new_letter == "\n":
        done = True
    gen_name = "".join(chain)
    self.bot.log("Generated "+gen_name[:-1])

    # Returns the name
    await ctx.send(gen_name)

  # Generates a random tavern name
  async def tavern_gen(self, ctx):
    # _lists first parts, second parts and third parts of tavern names
    first_part = ["The Silver","The Golden","The Staggering","The Laughing","The Prancing","The Gilded","The Running","The Howling","The Slaughtered","The Leering","The Drunken","The Leaping","The Roaring","The Frowning","The Lonely","The Wandering","The Mysterious","The Barking","The Black","The Gleaming","The Tap-Dancing","The Sad","The Sexy","The Artificial","The Groovy","The Merciful","The Confused","The Pouting","The Horny","The Okay","The Friendly","The Hungry","The Handicapped","The Fire-breathing","The One-Eyed","The Psychotic","The Mad","The Evil","The Idiotic","The Trusty","The Busty"]
    second_part = ["Eel","Dolphin","Dwarf","Pegasus","Pony","Rose","Stag","Wolf","Lamb","Demon","Goat","Spirit","Horde","Jester","Mountain","Eagle","Satyr","Dog","Spider","Star","Dad","Rat","Jeremy","Mouse","Unicorn","Pearl","Ant","Crab","Penguin","Octopus","Lawyer","Ghost","Toad","Handjob","Immigrant","SJW","Dragon","Bard","Sphinx","Soldier","Salmon","Owlbear","Kite","Frost Giant","Arsonist"]
    third_part = [" Tavern"," Inn","","","","","","","","",""]

    # Picks one of each
    gen_tav = random.choice(first_part)+" "+random.choice(second_part)+random.choice(third_part)
    self.bot.log("Generated "+gen_tav)

    # Return the name
    await ctx.send(gen_tav)
