# --------------------------------------------
# See http://www.tropo.com for more info
# --------------------------------------------

def make_test_versions_of_phone_functions():
  """Make this code work as a normal Python script -- good for debugging."""
  global ask, say, answer, hangup
  def ask(thing, other):
    print thing
    class Dummy: pass
    answer = Dummy()
    answer.name = "choice"
    answer.value = raw_input()
    return answer
  def say(thing): print thing
  def answer(): print "Answer"
  def hangup(): print "Hangup"

# Patch the code unless we're running on the phone
try:
    import os
    if 'nathan' in os.getcwd():
        make_test_versions_of_phone_functions()
except:
    pass

import urllib2
import urllib
import re

class StartOverException(Exception): pass

class GameOverException(Exception):
    def __init__(self, humanWon):
        Exception.__init__(self)
        self.humanWon = humanWon

def get_question_at_path(path):
    """Returns (question to ask, map from word to URL).  Or raises a GameOverException."""
    host = 'http://y.20q.net'
    page = urllib2.urlopen(host + path).read()
    if "You won!" in page:
        raise GameOverException(humanWon=True)
    if "You were thinking of" in page:
        raise GameOverException(humanWon=False)
    try:
        question = re.findall('<big><b>Q.*?;(.*?)<br><nobr>', page)[0]
        links = re.findall('href="(.*?)"', page)
        return question, dict(zip(['yes', 'no', "skip", 'irrelevant', 'sometimes', 'maybe', 'probably', 'doubtful', 'usually', 'depends', 'rarely', 'partly',], links))
    except:
        question = re.findall('<big><b>Q.*?;(.*?)<br>', page)[0]
        links = re.findall('href="(.*?)"', page)
        path_map = dict(zip(['right', 'wrong', 'close'], links))
        path_map['yes'] = path_map['right']
        path_map['no'] = path_map['wrong']
        return question, path_map


def instructions():
    say("Think of something and I will try to guess it.  I will ask you questions, and you can say: yes, no, irrelevant, sometimes, maybe, probably, doubtful, usually, depends, rarely, or partly.  Try to give the best answer if you want me to guess correctly.  If you don't know, say skip.  To repeat the question, say repeat.  To start the game over, say start over.  To hear this again, say instructions at any time.")


def get_answer(question, responses):
    """
    Ask the caller 'question', and wait for one of the strings in the
    'responses' list to be heard.  Returns the string that was heard, or raises
    a StartOverException if the caller said 'start over'.  (The caller can also
    say 'repeat' or 'instructions' which will cause something to be said back
    to them, but they will still then have to say something from the
    'responses' list.)
    """
    responses = responses + ['repeat', 'instructions', 'start_over']
    question = re.sub("<.*?>", "", question)
    while True:
        result = ask(question, dict(bargein=False, repeat=3, choices=','.join(responses)))
        if result.name != 'choice':
            say("I can't understand your crazy moon language.  Goodbye and good riddance!")
            hangup()
            raise Exception("Couldn't understand the user.")
        # Handle their query, or get a response
        say(result.value)
        if result.value == 'instructions':
            instructions()
            say("Let's continue.")
        elif result.value == 'repeat':
            pass # loop
        elif result.value == 'start_over':
            if 'really' == get_answer("If you really want to start over, say really, or say no to keep playing.", ["really", "no"]):
                raise StartOverException()
        else:
            return result.value
    

def play():
    """Play a game.  Return True if they want to play again, or False if not."""
    firstfetch = urllib2.urlopen('http://y.20q.net/anon-en').read()
    posturl = 'http://y.20q.net' + re.findall('action="(.*?)"', firstfetch)[0]
    postreq = urllib2.Request(posturl, urllib.urlencode(dict(age='28')))

    page = urllib2.urlopen(postreq).read()
    words = ["animal", "vegetable", "mineral", "something_else"]
    path_map = dict(zip(words, re.findall('href="(.*?)"', page)))

    answer = get_answer("Are you thinking of an animal, vegetable, mineral, or something else?", words)

    chosen_path = path_map[answer]
    question, path_map = get_question_at_path(chosen_path)

    while True:
        answer = get_answer(question, path_map.keys())
        try:
            chosen_path = path_map[answer]
            question, path_map = get_question_at_path(chosen_path)
        except GameOverException, e:
            if e.humanWon:
                say("You won! Good for you!")
            else:
                say("I won! Good for me!")
            return ('play_again' == get_answer("Say play again to play again, or say goodbye.", ["play_again", "goodbye"]))


answer()

say("Hello there. Welcome to 20 questions version oh point 2 by Michael Gunlock.")
if 'yes' == get_answer("Is this your first time calling?", ["yes", "no"]):
    say("Michael taught me to play 20 questions with you.  Here is how to play:")
    instructions()
    say("Let's begin.")
else:
    say("Welcome back.  Let's play.")
while True:
    try:
        if not play():
            break
    except StartOverException, e:
        pass
    say("Starting a new game")

say("nice playing with you!")

hangup()