#! /usr/bin/python

# ---------------------------------------------------------------------
#     **** LIBRARY SELECTION AND GLOBAL VARIABLE SETUP ****
# ---------------------------------------------------------------------
# import and initialize the pygame module
import pygame

# set up default values for the screen sizes
# (these can be overriden by the setup_pygame function)
screenSize = screenWidth,screenHeight = 480,320

# set up a default display and background image for the game
gameDisplay = None
background = None


# ---------------------------------------------------------------------
#     **** PYGAME/DISPLAY SETUP ROUTINE ****
# ---------------------------------------------------------------------
def setup_pygame(width, height):

   # make sure we use the global (shared) versions
   #    of the various screen size variables
   global screenSize, screenWidth, screenHeight
   global gameDisplay, background

   # initialize pygame and the display values
   pygame.init()
   screenSize = screenWidth,screenHeight = width,height
   gameDisplay = pygame.display.set_mode(screenSize)

   # load the background image
   background = pygame.image.load("backdrop.gif")


# ---------------------------------------------------------------------
#  **** CLASS TO DEFINE AND CONTROL OBJECTS THAT MOVE IN THE GAME ****
# ---------------------------------------------------------------------
class movingItem:

   def __init__(self, imageFile, (x,y)):
       # load the original image from a file
       self.Original = pygame.image.load(imageFile)

       # set up the initial facing of the item and rotate 
       #     its image to face that direction
       self.Facing = 0
       self.Image = pygame.transform.rotate(self.Original, self.Facing)

       # set up a box (rectangle) around the item
       self.Box = self.Image.get_rect()

       # set up the initial coordinates for the item
       self.Box.x = x
       self.Box.y = y

       # set the speed so the item is initially stationary
       self.Speed = [0,0]

   def update(self):

      # adjust the object's position based on its current speed
      self.Box = self.Box.move(self.Speed)

      # have the object 'wrap around' if it goes off the screen
      if self.Box.left > screenWidth:
         self.Box.right = 1
      elif self.Box.right < 0:
         self.Box.left = screenWidth - 1
      if self.Box.bottom < 0:
         self.Box.top = screenHeight - 1
      elif self.Box.top > screenHeight:
         self.Box.bottom = 1

      # rotate the object appropriately for its current facing
      self.Image = pygame.transform.rotate(self.Original, self.Facing)


# ---------------------------------------------------------------------
#     **** COLLISION HANDLING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles collisions between two movingItem objects
def handleCollision(item1, item2):
   red = 255,0,0
   if (item1.Box.colliderect(item2.Box)):
      pygame.draw.line(gameDisplay, red, (0, 0), (screenWidth, screenHeight), 5)
      pygame.draw.line(gameDisplay, red, (0, screenHeight), (screenWidth, 0), 5)
      pygame.display.flip()
      pygame.time.delay(1000)
   

# ---------------------------------------------------------------------
#     **** DISPLAY UPDATING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles updating and redrawing the display,
#    assuming it is given the background image and a list
#    of movingItems to update
def updateDisplay(bck, itemList):

   # remember to look up the global display variable
   global gameDisplay

   # redraw the background picture to the screen buffer
   gameDisplay.blit(background, (0,0))

   # redraw the items in the order they appear in the list
   for i in itemList:
      gameDisplay.blit(i.Image, i.Box)

   # update the visible display from the screen buffer
   pygame.display.flip()
   

# ---------------------------------------------------------------------
#     **** EVENT PROCESSING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine handles all event processing for the game
#    it assumes it is given two movingItems to manipulate,
#    the first one jumps when the player clicks on the display,
#    the second one's speed is controlled by the arrow keys
def handleEvents(jumpingItem, travelingItem):

   # check for all events that have taken place during
   #    this turn (keypresses, mouseclicks, etc)
   #    and process them one at a time
   for event in pygame.event.get():

      # check to see if the player clicked the window close box
      if event.type == pygame.QUIT:
         keepPlaying = False
         print "Player command: close window"

      # if the player clicked on the screen
      #    have the star "jump" to the new location
      if event.type == pygame.MOUSEBUTTONDOWN:
         jumpingItem.Box.center = event.pos

      # check to see if the player pressed any keys
      if event.type == pygame.KEYDOWN:

         # treat the Q key as a quit command
         if event.key == pygame.K_q:
            print "Player command: quit (q)"
            return False

	 elif event.key == pygame.K_UP:
	    travelingItem.Speed = [0, -4]
	    travelingItem.Facing = 45

	 elif event.key == pygame.K_DOWN:
	    travelingItem.Speed = [0, 4]
	    travelingItem.Facing = 225

	 elif event.key == pygame.K_LEFT:
	    travelingItem.Speed = [-4, 0]
	    travelingItem.Facing = 135

	 elif event.key == pygame.K_RIGHT:
	    travelingItem.Speed = [4, 0]
	    travelingItem.Facing = 315

      # end of the events for loop

   # none of the events said to quit, so return True
   return True


# ---------------------------------------------------------------------
#     **** MAIN CONTROL/PROCESSING ROUTINE FOR THE GAME ****
# ---------------------------------------------------------------------
# this routine controls the operational portion of the game,
#    assuming the pygame setup routine has already been run
def mainGame():

   # create the moving star and ship
   star = movingItem('star.gif', (100,100))
   ship = movingItem('ship.gif', (200,200))

   # run the game loop
   keepPlaying = True
   numCollisions = 0
   while keepPlaying:
   
      # update the facing, speed, and position of 
      #    the star and the ship
      ship.update()
      star.update()

      # check for collisions between the star and the ship
      handleCollision(star, ship)

      # redraw the display
      updateDisplay(background, [star, ship])

      # pause for 20 milliseconds before continuing
      pygame.time.delay(30)

      # handle any pending events
      keepPlaying = handleEvents(star, ship)

      # end of the keepPlaying while loop


# ---------------------------------------------------------------------
#     **** RUN THE SETUP AND MAIN GAME ROUTINES ***
# ---------------------------------------------------------------------
setup_pygame(640,480)
mainGame()
print "shutting down the game"
# ---------------------------------------------------------------------
#     **** END OF PROGRAM ****
# ---------------------------------------------------------------------

