"""
This program allows the user to "draw" on a grid of characters.  The user enters
commands, which are then drawn on a text canvas.  After each command, the canvas
is displayed to the user.

This program is intended as a demonstration during lecture and will be updated
by students at that time.  For that reason, the author information below may not
be complete.

Original Author: Zachary Palmer
Original Date: 2015-10-05
"""

def create_empty_canvas(width, height):
  # Our canvas will be a list of lists of single-character strings.  The outer
  # list represents the entire canvas; each inner list is a row of characters.
  # For instance, [["a","b","c"],["d","e","f"]] would represent the 3x2 canvas
  # drawn like this:
  #     abc
  #     def
  # We will start by creating the canvas as an empty list.  Then, for each row,
  # we will create a list of the appropriate length (the width of the canvas)
  # and append it to the original list.
  canvas = []
  for row_number in range(height):
    # Create a row of the right width.
    row = []
    for column_number in range(width):
      row.append(".")
    # Add that row to the canvas.
    canvas.append(row)
  return canvas

def show_canvas(canvas):
  # For each row...
  for row in canvas:
    # Use a string accumulator to create a string for this row.
    line = ""
    for c in row:
      line += c
    # Print the string for this row.
    print line

def clear(canvas):
  # For each position in the entire canvas, clear it.
  for row in canvas:
    for i in range(len(row)):
      row[i] = "."

def draw_rectangle(canvas, x, y, w, h, c):
  # For each position in the rectangle, draw a character onto the canvas.
  for i in range(x,x+w):
    for j in range(y,y+h):
      canvas[j][i] = c

def draw_box(canvas, x, y, w, h, c):
  # Draw the top and bottom of the box first.
  for i in range(x,x+w):
    canvas[y][i] = c
    canvas[y+h-1][i] = c
  # Then draw the sides.
  for i in range(y,y+h):
    canvas[i][x] = c
    canvas[i][x+w-1] = c

def main():
  canvas_width = 20
  canvas_height = 8
  canvas = create_empty_canvas(canvas_width, canvas_height)

  # Now we enter our command loop.  We will accept commands from the user until
  # the "quit" command, which ends the program.  We accept the first command
  # outside of the loop so that the loop can end once "quit" has been entered.
  print "Here is your canvas:"
  show_canvas(canvas)
  command = raw_input("What would you like to do? ")
  while command != "quit":
    if command == "rectangle":
      x = int(raw_input("Where would you like the rectangle (x-coordinate in [0..%d])? " % (canvas_width-1)))
      y = int(raw_input("Where would you like the rectangle (y-coordinate in [0..%d])? " % (canvas_height-1)))
      w = int(raw_input("How wide would you like the rectangle? "))
      h = int(raw_input("How tall would you like the rectangle? "))
      c = raw_input("What character would you like to use for the rectangle? ")
      draw_rectangle(canvas, x, y, w, h, c)
    elif command == "box":
      x = int(raw_input("Where would you like the box (x-coordinate in [0..%d])? " % (canvas_width-1)))
      y = int(raw_input("Where would you like the box (y-coordinate in [0..%d])? " % (canvas_height-1)))
      w = int(raw_input("How wide would you like the box? "))
      h = int(raw_input("How tall would you like the box? "))
      c = raw_input("What character would you like to use for the box? ")
      draw_box(canvas, x, y, w, h, c)
    elif command == "clear":
      clear(canvas)
    else:
      print "I don't know the command \"%s\"." % command
    print "Here is your canvas."
    show_canvas(canvas)
    command = raw_input("What would you like to do now? ")
  print "Goodbye!"

main()

