#! /usr/bin/python


# import the necessary libraries
import sys, pygame, math
from pygame.locals import *

# initialize pygame
pygame.init()

# ==================================================================
#  Game Settings
#

# set the width and height of the game window
size = width, height = 960,720

# run the game as a widthxheight windowed mode
# (to run in full screen add the ,FULLSCREEN parameter in the set_mode call)
screen = pygame.display.set_mode(size)
# load the background image
background = pygame.image.load("../images/backdrop.gif")
screen.blit(background, (0,0))

# each turn lasts the specified number of milliseconds,
turn_number = 0
# set the time delay amount, in milliseconds
milliseconds_delay = 33
# compute a maximum number of turns for the game
max_game_minutes = 2 
max_turns = max_game_minutes * 60000 / milliseconds_delay

# ==================================================================
#  The Ship Sprite
#
class ShipSprite(pygame.sprite.Sprite):
    # set constants for top speed, acceleration (thrust), and
    #     turn mode (how far the vessel can turn in one step)
    top_speed = 31
    top_reverse = -15
    thrust = 1
    turnmode = 2
    # the constructor
    def __init__(self, image, position, direction, speed):
        # call the parent Sprite constructor
        pygame.sprite.Sprite.__init__(self)
        # load the image to be used for this ship from the parameter
        self.src_image = pygame.image.load(image)
        self.image = self.src_image
        # set the ship facing, speed, and position from the parameters
        self.position = position
        self.speed = speed
        # direction is based on 0-359 degree heading going COUNTER-clockwise
        self.direction = direction
        # keep track of whether or not the ship is accelerating/decelerating
        #   or turning to the left or right
        self.turning_left = 0
        self.turning_right = 0
        self.accelerating = 0
        self.decelerating = 0
        
    # the update ship is used to apply speed and direction changes
    def update(self):
        # update the speed and direction
        if self.accelerating == 1:
            self.speed += self.thrust
            if (self.speed > self.top_speed):
                self.speed = self.top_speed
        if self.decelerating == 1:
            self.speed -= self.thrust
            if (self.speed < self.top_reverse):
                self.speed = self.top_reverse
        if self.turning_left == 1:
            self.direction += self.turnmode
            if (self.direction > 359): self.direction -= 360
        if self.turning_right == 1:
            self.direction -= self.turnmode
            if (self.direction < 0): self.direction += 360
        # compute the amount to move in each direction and
        #   the resulting new x,y coordinates for the ship
        x,y = self.position
        rad = self.direction * math.pi / 180
        x += -self.speed*math.sin(rad)
        y += -self.speed*math.cos(rad)
        self.position = (x,y)
        # stop the ship if it hits a wall
        if x < 8:
            x = 8
            self.speed = 0
        if x > width-8:
            x = width-8
            self.speed = 0
        if y < 16:
            y = 16
            self.speed = 0
        if y > height-8:
            y = height-8
            self.speed = 0
        # rotate the ship image to face the desired direction
        self.image = pygame.transform.rotate(self.src_image, self.direction)
        # position the ship, centered at the new x,y coordinates
        self.rect = self.image.get_rect()
        self.rect.center = self.position
        
# ==================================================================
#  The Game Loop
#

# create a ship, passing the image, position, direction, and speed
ship = ShipSprite("../images/ship.gif", (100,100), 225, 0)
# create a group for the sprite type
ship_group = pygame.sprite.RenderPlain(ship)

# start the event loop, each pass will
#    see if we should quit (player closed window)
#    record player decisions to turn, accelerate, or decelerate
#    call update to move the ship
#    colour over the entire background with black
#    redraw the ship
#    flip from the old window image to the new one
while turn_number < max_turns:
    # update the number of turns played so far
    turn_number += 1
    # event.get grabs all the events waiting to be processed
    for event in pygame.event.get():
        # if the user clicked the close box, shut down
        if event.type == pygame.QUIT:
            sys.exit()
        if not hasattr(event, 'key'): continue
        # see if the key is up or down
        keyon = 0
        if event.type == KEYDOWN: keyon = 1
        # process decisions to start or stop turning or changing speed
        if event.key == K_RIGHT:
            if keyon == 1: ship.turning_right = 1
            else: ship.turning_right = 0
        elif event.key == K_LEFT:
            if keyon == 1: ship.turning_left = 1
            else: ship.turning_left = 0
        elif event.key == K_DOWN:
            if keyon == 1: ship.decelerating = 1
            else: ship.decelerating = 0
        elif event.key == K_UP:
            if keyon == 1: ship.accelerating = 1
            else: ship.accelerating = 0
        # process decisions to quit using escape
        elif event.key == K_ESCAPE:
            sys.exit()
            
    # update the display
    #   clear the image of the ship
    #       (replacing it with whatever is behind it in the background)
    #   call update and draw the ship image in its new location
    ship_group.clear(screen, background)
    ship_group.update()
    ship_group.draw(screen)
    # flip is used to swap from the old screen image to the new one                             
    pygame.display.flip()
    # introduce a short time delay before the next turn starts
    pygame.time.delay(milliseconds_delay) 
    
# game over!
sys.exit()

