from livewires import *
begin_graphics()

#### Vehicle Components ####

def tyre(x,y,r):
    circle(x,y,r, colour=Colour.black, filled=1)
    circle(x,y,r/3, colour=Colour.white, filled=1)
def mudguard(x,y,r):
    circle(x,y, endpoints=((x+r+3,y),(x-r-3,y)), colour=Colour.white, filled=1)
    circle(x,y, endpoints=((x+r+3,y),(x-r-3,y)), colour=Colour.blue)
def wheel(x,y,r):
    mudguard(x,y,r)
    tyre(x,y,r)
def double_wheel(x,y,r):
    wheel(x,y,r)
    wheel(x-(2*r+10),y,r)

def sedan_front(x,y):
    box((x,y),(x-60,y+20), filled=1)
    move(x-20,y+20)
    draw(x-40,y+40)
    draw(x-60,y+40)
    draw(x-60,y+20)
def sedan_rear(x,y):
    box((x-60,y),(x-120,y+20), filled=1)
    move(x-60,y+40)
    draw(x-100,y+40)
    draw(x-105,y+20)
    move(x-100,y+40)
    draw(x-100,y+20)
def sedan(x,y):
    sedan_front(x,y)
    r = 7
    wheel(x-20,y,r)
    sedan_rear(x,y)
    wheel(x-90,y,r)

def taxi(x,y):
    set_colour(Colour.yellow)
    sedan(x,y)
    polygon(((x-50,y+40),(x-52,y+47),(x-55,y+47),(x-57,y+40)), filled=1)

def wagon_rear(x,y):
    box((x-60,y),(x-130,y+20), filled=1)
    move(x-60,y+40)
    draw(x-128,y+40)
    draw(x-130,y+20)
    move(x-100,y+40)
    draw(x-100,y+20)
def wagon(x,y):
    sedan_front(x,y)
    r = 7
    wheel(x-20,y,r)
    wagon_rear(x,y)
    wheel(x-100,y,r)

def convertible_body(x,y,scale,stretch):
    box((x,y),(x-100*scale-stretch,y+20*scale), filled=1)
    move(x-20*scale,y+20*scale)
    draw(x-40*scale,y+40*scale)
def convertible(x,y):
    scale = random_between(7,10) / 10.0
    stretch = random_between(0,20)
    r = 7
    convertible_body(x,y,scale,stretch)
    wheel(x-20*scale,y,r*scale)
    wheel(x-80*scale-stretch,y,r*scale)

def beetle_body(x,y):
    circle(x-40,y+10, endpoints=((x-16,y+20),(x-64,y+20)))
    move(x-40,y+20)
    draw(x-40,y+35)
    circle(x-20,y, endpoints=((x,y),(x-20,y+20)), filled=1)
    box((x-20,y),(x-63,y+20), filled=1 )
    circle(x-50,y, endpoints=((x-63,y+22),(x-75,y)), filled=1)
def beetle(x,y):
    beetle_body(x,y)
    r = 6
    wheel(x-15,y,r)
    wheel(x-60,y,r)

def ute_rear(x,y):
    box((x-60,y+5),(x-130,y+20), filled=1)
    move(x-65,y+40)
    draw(x-65,y+20)
def ute(x,y):
    sedan_front(x,y)
    r = 7
    mudguard(x-20,y,r)
    tyre(x-20,y-2,r)
    ute_rear(x,y)
    mudguard(x-100,y,r)
    tyre(x-100,y-2,r)

def truck_front(x,y):
    box((x,y),(x-50,y+35), filled=1)
    box((x-40,y+35),(x-50,y+60), filled=1)
    move(x-20,y+35)
    draw(x-25,y+60)
    draw(x-40,y+60)
def pantech_rear(x,y):
    box((x-55,y+5),(x-170,y+80), filled=1)
    box((x-50,y+5),(x-55,y+8), filled=1)
def pantech(x,y):
    truck_front(x,y)
    r = 10
    wheel(x-35,y,r)
    pantech_rear(x,y)
    mudguard(x-120,y,r)
    double_wheel(x-120,y,r)

def semi_rear(x,y):
    box((x-65,y+5),(x-250,y+80), filled=1)
    box((x-50,y+5),(x-65,y+8), filled=1)
def semi(x,y):
    truck_front(x,y)
    r = 10
    wheel(x-35,y,r)
    semi_rear(x,y)
    double_wheel(x-80,y,r)
    double_wheel(x-200,y,r)

#### Get Input from Human ####

# def grid: Draw a grid.
def grid(g):
    set_colour(Colour.red)
    for b in range(4):
        move(0 + g, b * 100 + g)
        draw(300 + g, b * 100 + g)
        move(b * 100 + g, 0 + g)
        draw(b * 100 + g, 300 + g)

# def vehicle_text: Write the choices.
def vehicle_text(t):
    set_colour(Colour.blue)
    choices = ["sedan", "taxi", "wagon", "convertible", "none", "beetle", "ute", "pantech", "semi"]
    n = 0
    for b in choices[:3]:                       # For items from the start of the list, stop at 3.
                                                # That is, items 0, 1, 2.
        move(n + t, 200 + t)
        text(b)
        n = n + 100
    n = 0
    for b in choices[3:6]:                      # For items 3 onwards, stop at 6.
                                                # That is, items 3, 4, 5.
        move(n + t, 100 + t)
        text(b)
        n = n + 100
    n = 0
    for b in choices[6:]:                       # For items 6 onwards, to the end of the list.
                                                # That is, items 6, 7, 8.
        move(n + t, 0 + t)
        text(b)
        n = n + 100

# def ask: Layout a screen that invites a human to click on a type of vehicle.
def ask(g, t):
    move(50, 400)
    text("Click on the vehicle you would like to see.", size=20, colour=Colour.black)
                                                # The " " are important.
    grid(g)
    vehicle_text(t)

# def get_mouse: Obtain position of mouse when it is clicked.
def get_mouse():
    begin_mouse()                               # Look for mouse behaviour.
    mouse_wait(how="click")                     # Wait for a mouse click.
    mp = mouse_position()                       # Returns mouse's x and y position.
                                                # Mouse's x position is mp[0].
                                                # Mouse's y position is mp[1].
    end_mouse()                                 # Stop looking for mouse behaviour.
    return mp                                   # Give back the result.

# def which_stripe: Work out which grid column/row was clicked in,
#                   by reverse engineering the placement of the grid lines.
def which_stripe(g, m):
    calculate_stripe = (m - g) / 100            # Since all the inputs to the equation are integers,
                                                # dividing using / will give an integer answer.
                                                # / will return the quotient and discard the remainder.
    if 0 <= calculate_stripe <= 2:              # If the integer is 0, 1, or 2.
        stripe = calculate_stripe
    else:
        move(50,25)
        text("You did not click in a square. Please try again.", colour=Colour.pink)
        stripe = "missed"
    return stripe

# def which_vehicle: Work out which type of vehicle was selected.
def which_vehicle(column, row):
    vehicles = [sedan, taxi, wagon, convertible, 0, beetle, ute, pantech, semi]
    if row == 0:                                # Bottom row.
        vehicle_type = vehicles[column + 6]
    elif row == 1:                              # Middle row.
        vehicle_type = vehicles[column + 3]
    elif row == 2:                              # Top row.
        vehicle_type = vehicles[column + 0]
    return vehicle_type

# def response: Work out which grid square was clicked in, and return corresponding vehicle type.
# Input: Mouse position, known location of grid lines.
# Output: Chosen vehicle type.
def response(g):
    while True:                                         # do until told to stop.
        mp = get_mouse()                                # Get mouse position.
        column = which_stripe(g, mp[0])                 # Determine column.
        row = which_stripe(g, mp[1])                    # Determine row.
        if column == "missed" or row == "missed":       # If click was outside the grid,
            continue                                    # go back to the beginning of the loop.
        else:                                           # Otherwise,
            vehicle_type = which_vehicle(column, row)   # determine type of vehicle.
        break
    return vehicle_type

# def another_picture: Invite human to continue or quit. Obtain answer via keyboard, and return answer.
def another_picture():
    move(50, 25)
    text("Do you want another picture? (y,n)", colour=Colour.black)
    while True:
        keys = []                               # Set the list to be empty.
        keys = wait_for_keys()                  # Wait for keyboard activity.
                                                # Returns a list of those that were pressed.
        if "y" in keys:                         # Check if "y" is in the list.
            return True
        elif "n" in keys:
            return False

#### Draw picture as requested ####

def draw_vehicle(vehicle_type):
    Colour.orange = Colour(1.0,0.6,0.0)
    colours = [Colour.red, Colour.green, Colour.blue, Colour.orange, Colour.pink, Colour.purple]
    set_colour(colours[random_between(0,5)])    # Randomly choose from the list of colours.
    vehicle_type(300,200)

#### Putting it all together ####

# def main_loop: Continue iterations of program until told to stop.
def main_loop():
    g = 50                                      # Grid offset from edge of window.
    t = 60                                      # Text offset from edge of window.
    while True:                                 # While True, do the following:
        clear_screen()
        ask(g, t)                               # Request type of vehicle to draw.
        vehicle_type = response(g)              # Work out which type of vehicle was selected.
        if vehicle_type == 0:                   # If asked for no vehicle to be drawn,
            break                               # then stop.
        else:
            clear_screen()
            draw_vehicle(vehicle_type)          # Draw the type of vehicle that was selected.
        if not another_picture():               # If invitation to continue or quit returns False,
            break                               # then stop.

main_loop()

end_graphics()
