text: import sqlite3        
  import re
  from errors import ExitApp
  from input_manager import rem_space_specialchar, get_word_info, get_list_info
  from wordlist_manager import prep_fill_in_the_blank, test_fill_in_the_blank,  rem_word_from_sentence, test_flashcards, show_score, test_multiplechoice
  
  
  class Collect_Vocab:
      def __init__(self,database):
          self.database = database
          self.conn = sqlite3.connect(self.database)
          self.c = self.conn.cursor()
          
          
  # Set up the user's account: logging in or registering
  
      def get_username(self):
          print("\nUsername: ")
          username = input("Spaces and special characters will be removed: ")
          username = rem_space_specialchar(username)
          if 'exit' == username.lower():
              raise ExitApp("Aw man. I didn't even catch your name. Come back soon!") 
          if username:
              return username
          else:
              print("Not enough alphanumeric characters used. Try again.")
              self.get_username()
          return None
      
      def get_password(self):
          print("\nPassword: ")
          password = input()
          return password
      
      def login(self,username):
          print("\nEnter your password to access your lists.\n")
          password = self.get_password()
          if 'exit' == password.lower():
              raise ExitApp("Aw man. You're leaving already? Come back soon!") 
          if password:
              match = self.check_password(username, password)
              return match
          return None
          
      def register(self,username):
          print("\nWelcome {}! Enter a password to create your account".format(username))
          password = self.get_password()
          if password:
              self.add_user(username,password)
              return True
          else:
              return False
  
      def sign_in(self):
          username = self.get_username()
          exist, user_id = self.check_if_user_exists(username)
          if exist == False:
              print("\nYour username will be saved as '{}'".format(username))
              logged_in = self.register(username)
          else:
              print("\nWelcome back {}! \n".format(username))
              logged_in = self.login(username)
              if logged_in == False:
                  print("Either the password is incorrect or the username is taken. Please try again.")
                  self.sign_in()
          return None
          
      def access_users_table(self):
          msg = '''CREATE TABLE IF NOT EXISTS users(user_id integer primary key, username text, password text)'''
          self.c.execute(msg)
          self.conn.commit()
          return None
      
      def check_if_user_exists(self,username):
          self.access_users_table()
          t = (username,)
          self.c.execute('''SELECT * FROM users WHERE username=? ''', t)
          users = self.c.fetchall()
          if len(users) == 1:
              return True, users[0][0]
          elif len(users) == 0:
              return False, None
          return None, None
      
      def check_password(self,username, password):
          t = (username,)
          msg = '''SELECT password FROM users WHERE username=? ''' 
          self.c.execute(msg,t)
          real_password = self.c.fetchall()[0][0]
          if password == real_password:
              self.is_user = True
              self.username = username
              _, self.user_id = self.check_if_user_exists(username)
              return True
          else:
              self.is_user = False
          return False
          
      def get_info(self):
          msg = "\nFor each list of words you create, you can add tags and example sentences.\n\nYou can even test your knowledge with flashcards, multiple choice and fill-in-the-blank quizzes.\n"
          print(msg)
          return None
          
      def add_user(self,username,password):
          self.username = username
          t = (username,password,)
          msg = '''INSERT INTO users VALUES (NULL,?,?) '''
          self.c.execute(msg,t)
          self.conn.commit()
          self.is_user, self.user_id = self.check_if_user_exists(username)
          print("\nYou're account has been created.\nGet started by creating your first list.\n")
          self.get_info()
          
          return None
      
      
  # Actions the logged_in user can do:
      
      def action_list(self):
          if self.is_user == True:
              print("\nAction:\n1) open existing list\n2) create new list")
              action_int = input("Enter 1 or 2 (or exit): ")
              action_int = rem_space_specialchar(action_int)
              if action_int.isdigit():
                  if int(action_int) == 1:
                      self.check_lists()
                      self.action_word()
                  elif int(action_int) == 2:
                      list_name,list_tags = get_list_info()
                      self.create_new_list(list_name,list_tags)
                      self.action_word()
              else:
                  if 'exit' in action_int.lower():
                      self.is_user = False
                      self.action_list()
                  else:
                      print("\nPlease enter 1 or 2\n".upper())
                      self.action_list()
          else:
              raise ExitApp("Good job learning words! Until the next time :)")
          return None
      
      def action_word(self):
          print("\nAction:\n1) add word\n2) review words \n3) change list")
          action_int = input("Enter 1, 2, 3 (or exit): ")
          action_int = rem_space_specialchar(action_int)
          if action_int.isdigit():
              if int(action_int) == 1:
                  word,meaning,example,tags = get_word_info()
                  self.add_word(word,meaning,example,tags)
                  self.action_word()
              elif int(action_int) == 2:
                  self.quiz_wordlist()
              elif int(action_int) == 3:
                  self.action_list()
          else:
              if 'exit' in action_int.lower():
                  self.is_user = False
                  self.action_list()
              else:
                  print("\nPlease enter 1 or 2\n".upper())
                  self.action_word()
          return None
      
      def access_user_vocablists(self):
          msg = '''CREATE TABLE IF NOT EXISTS vocab_lists(list_id integer primary key, list_name text, list_number int, tags text, list_user_id integer, FOREIGN KEY(list_user_id) REFERENCES users(user_id) )'''
          self.c.execute(msg)
          self.conn.commit()
          return None
      
      def choose_list(self):
          print("\nHere are your lists")
          for key, value in self.dict_lists.items():
              print(value[1],'--> ',key)
          print("\nTable of interest: (enter the corresponding number) ")
          curr_list_num = input()
          curr_list_num = rem_space_specialchar(curr_list_num)
          if curr_list_num.isdigit():
              curr_list_num = int(curr_list_num)
          else:
              if 'exit' in curr_list_num.lower():
                  self.is_user = False
                  self.action_list()
              else:
                  print("\nPlease enter the corresponding number\n".upper())
          for key,value in self.dict_lists.items():
              if curr_list_num == value[1]:
                  self.curr_list_id = value[0]
                  return None
          else:
              print("\nPlease choose a corresponding number\n".upper())
              self.choose_list()
          return None
      
      def coll_user_vocab_lists(self):
          self.access_user_vocablists()
          t = (str(self.user_id),)
          msg = '''SELECT * FROM vocab_lists WHERE list_user_id=? ''' 
          self.c.execute(msg, t)
          lists = self.c.fetchall()
          return lists
      
      def check_lists(self):
          lists = self.coll_user_vocab_lists()
          if len(lists) == 0:
              print("It looks like you don't have a list. Start one now!")
              name,tags = get_list_info()
              self.create_new_list(name,tags)
              self.action_word()
          else:
              self.dict_lists = {}
              for list_index in range(len(lists)):
                  name_of_list = lists[list_index][1]
                  self.dict_lists[name_of_list] = (lists[list_index][0],lists[list_index][2])
              self.choose_list()
          return None
      
      def get_list_id(self,list_name,tags):
          t = (list_name,tags)
          msg = '''SELECT list_id FROM vocab_lists WHERE list_name=? AND tags=? '''
          self.c.execute(msg,t)
          list_id = self.c.fetchall()[0][0]
          return list_id
      
      def create_new_list(self,name,tags):
          lists = self.coll_user_vocab_lists()
          list_num = len(lists)+1
          msg = '''INSERT INTO vocab_lists VALUES (NULL, ?,?,?,?) '''
          t = (name,list_num,tags,str(self.user_id))
          self.c.execute(msg,t)
          self.conn.commit()
          self.curr_list_id = self.get_list_id(name,tags)
          self.curr_list_name = name
          return None
          
      def access_word_table(self):
          msg = '''CREATE TABLE IF NOT EXISTS words(word_id integer primary key, word text, meaning text, example_sentence text, tags text, word_list_id integer, FOREIGN KEY(word_list_id) REFERENCES vocab_lists(list_id)) '''
          self.c.execute(msg)
          self.conn.commit()
          return None
      
      
      def add_word(self,word,meaning,example,tags):
          self.access_word_table()
          msg = '''INSERT INTO words VALUES (NULL, ?,?,?,?,?) '''
          if isinstance(self.curr_list_id,int):
              curr_list_id = str(self.curr_list_id)
          else:
              curr_list_id = self.curr_list_id
          t = (word,meaning,example,tags,curr_list_id)
          self.c.execute(msg,t)
          self.conn.commit()
          return None
      
      def coll_word_meanings(self):
          t = (str(self.curr_list_id))
          msg = '''SELECT word, meaning from words WHERE word_list_id=? '''
          self.c.execute(msg,t)
          word_meaning_data = self.c.fetchall()
          return word_meaning_data
      
      def quiz_flashcard(self):
          word_meaning_data = self.coll_word_meanings()
          if len(word_meaning_data) == 0:
              print("\nNo word meanings found.\n")
              return None
          score = test_flashcards(word_meaning_data)
          show_score(score)
          self.action_word()
          return None
      
      def quiz_multchoice(self):
          word_meaning_data = self.coll_word_meanings()
          if len(word_meaning_data) == 0:
              print("\nNo word meanings found.\n")
              return None
          score = test_multiplechoice(word_meaning_data)
          show_score(score)
          self.action_word()
          return None
      
      def coll_word_examples(self):
          t = (str(self.curr_list_id))
          msg = '''SELECT word, example_sentence FROM words WHERE word_list_id=? '''
          self.c.execute(msg,t)
          words_examples = self.c.fetchall()
          if len(words_examples) == 0:
              print("\nNo example sentences found.\n")
              return None
          return words_examples
      
      def quiz_fillblank(self):
          words_examples = self.coll_word_examples()
          word_example_list = prep_fill_in_the_blank(words_examples)
          word_blank_list = rem_word_from_sentence(word_example_list)
          score = test_fill_in_the_blank(word_blank_list)
          if score != None:
              show_score(score)
          self.action_word()
          return None
      
      def show_words(self):
          word_meaning_data = self.coll_word_meanings()
          print("\nWords in this list: ")
          if len(word_meaning_data) == 0:
              print("You haven't entered any words yet.")
          else:
              for word in word_meaning_data:
                  print("{} : {}".format(word[0],word[1]))
          self.action_word()
          return None
      
      def quiz_wordlist(self):
          #create word table just in case one doesn't exist yet
          self.access_word_table()
          print("\nReview:\n1) Flashcards\n2) Multiple Choice\n3) Fill in the blank\n4) View all words and their meanings")
          quiz_type = input("Enter 1, 2, 3, 4 (or exit): ")
          if quiz_type.isdigit():
              if int(quiz_type) == 1:
                  self.quiz_flashcard()
              elif int(quiz_type) == 2:
                  self.quiz_multchoice()
              elif int(quiz_type) == 3:
                  self.quiz_fillblank()
              elif int(quiz_type) == 4:
                  self.show_words()
          else:
              if 'exit' in quiz_type.lower():
                  self.is_user = False
                  self.action_list()
              else:
                  print("\nPlease enter 1, 2, 3, or 4\n".upper())
                  self.quiz_wordlist()
          return None
  