'''
May 2017 Puzzle
(http://web.monroecc.edu/MathPuzzler/May17puzzle)

When frosting a 9-inch by 12-inch rectangular cake using red,
white, and blue frosting, Emily accidentally applied the frosting
incorrectly.  The frosting was supposed to be applied in 3-inch
by 12-inch strips as shown in Figure 2 below. However, she applied
it in 4-inch by 9-inch strips as shown in Figure 1.  Being the
clever person that she is, Emily figured out a way to cut the cake
into four pieces in order to reassemble them in the desired form.
How did she do it?

RRRRWWWWBBBB          RRRRRRRRRRRR
RRRRWWWWBBBB          RRRRRRRRRRRR
RRRRWWWWBBBB          RRRRRRRRRRRR
RRRRWWWWBBBB          WWWWWWWWWWWW
RRRRWWWWBBBB          WWWWWWWWWWWW
RRRRWWWWBBBB          WWWWWWWWWWWW
RRRRWWWWBBBB          BBBBBBBBBBBB
RRRRWWWWBBBB          BBBBBBBBBBBB
RRRRWWWWBBBB          BBBBBBBBBBBB

  Figure 1              Figure 2
'''

import graphics as g
import time

rSize = 10                #Number of pixels for each little rectangle

class myRectangle(g.Rectangle):
  '''
  Create a rectangle with a fill color.  Position at x, y
  '''
  
  def __init__(self, x, y, color):

    #super(...) doesn't work here (old style vs new style classes???)
    g.Rectangle.__init__(self, g.Point(x, y), g.Point(x+rSize, y+rSize))
    self.color = color
    self.setFill(self.color)

  def getColor(self):
    return self.color

def moveSections(ll, ld, ml, md, rl, rd):
  '''
    Move the left section by ll left and ld down, the middle right section by ml/md,
    and the right section by rl/rd.  (The middle left section is not moved.)
    The values of ll, ld, etc... are in pixels.
  '''

  #Move the left-most section (Section 1)
  for x in left:                    #Move each rectangle in the left section
    rect[x[0]][x[1]].move(ll, ld)   # ll to the left and ld down

  #Move the middle right section (Section 3)
  for x in midright:                #Ditto for the other sections
    rect[x[0]][x[1]].move(ml, md)

  #Move the right-most section (Section 4)    
  for x in right:
    rect[x[0]][x[1]].move(rl, rd)

  w.getMouse()                      #Wait for mouse click
  


################
#  Main
################
if __name__ == '__main__':

  #Set "the table" for the cake
  w = g.GraphWin("Cake Repair", 225, 225)

  #Create an array to hold all the individual small rectangles
  #of the cake (9x12)
  rect = [[0 for x in range(12)] for y in range(9)]     

  #Create and display the cake in its original (incorrect) shape   
  for row in range(0, 9):
    for col in range(0, 4):
      rect[row][col] = myRectangle(10*col+50, 10*row+50, "red")
      rect[row][col].draw(w)
      
  for row in range(0, 9):
    for col in range(4, 8):
      rect[row][col] = myRectangle(10*col+50, 10*row+50, "white")
      rect[row][col].draw(w)
      
  for row in range(0, 9):
    for col in range(8, 12):
      rect[row][col] = myRectangle(10*col+50, 10*row+50, "blue")
      rect[row][col].draw(w)

  #Signal user how to use this application
  g.Text(g.Point(110,200),"Click the mouse to advance").draw(w)

  #View the incorrectly frosted cake for an instant
  w.getMouse()

  #Generate the starting cake's 4 sections (problem solution)
  #Section 1 - left-most section
  left = [(x,0) for x in range(9)]
  left += [(x,1) for x in range(3,9)]
  left += [(x,2) for x in range(6,9)]

  #Section 2 - Center left section
  midleft = [(x,1) for x in range(3)]
  midleft += [(x,2) for x in range(6)]
  midleft += [(x,3) for x in range(9)]
  midleft += [(x,4) for x in range(9)]
  midleft += [(x,5) for x in range(6)]
  midleft += [(x,6) for x in range(3)]

  #Section 3 - Center right section
  midright = [(x,5) for x in range(6,9)]
  midright += [(x,6) for x in range(3,9)]
  midright += [(x,7) for x in range(9)]
  midright += [(x,8) for x in range(9)]
  midright += [(x,9) for x in range(3,9)]
  midright += [(x,10) for x in range(6,9)]

  #Section 4 - Right-most section
  right = [(x,9) for x in range(3)]
  right += [(x,10) for x in range(6)]
  right += [(x,11) for x in range(9)]

  #Move the sections to show the solution is correct
  moveSections(-10,0,10,0,20,0)     #Section 1 left; Section 3 right; Section 4 right x 2
  moveSections(-10,0,10,0,10,0)     
  moveSections(0,10,0,10,0,0)       #Section 1 down; Section 3 down; Section 4 don't move
  moveSections(0,10,0,10,0,0)
  moveSections(0,10,0,10,0,0)
  moveSections(10,0,-10,0,-10,0)    #Section 1 right; Section 3 up; Section 4 left
  moveSections(10,0,-10,0,-10,0)    #  ...etc.
  moveSections(10,0,-10,0,-10,0)
  moveSections(0,0,0,0,-10,0)
  moveSections(0,0,0,0,-10,0)
  

  #Rotate cake to show in the position of the puzzle description
  for row in rect:
    for element in row:
      p1 = element.getP1()      #Current position of small rectangle
      element.undraw()          # remove it
      
      #Rotate 90 degrees and redraw (by swapping X and Y)
      myRectangle(p1.getY(), p1.getX(), element.getColor()).draw(w)

  #time.sleep(5)
  w.getMouse()
  w.close()