#    This file is part of Slingshot.
#
# Slingshot is a two-dimensional strategy game where two players attempt to shoot one
# another through a section of space populated by planets.  The main feature of the
# game is that the shots, once fired, are affected by the gravity of the planets.

# Slingshot is Copyright 2007 Jonathan Musther and Bart Mak. It is released under the
# terms of the GNU General Public License version 2, or later if applicable.

# Slingshot is free software; you can redistribute it and/or modify it under the terms
# of the GNU General Public License as published by the Free Software Foundation; either
# version 2 of the License, or any later version.

# Slingshot is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.

# You should have received a copy of the GNU General Public License along with Slingshot;
# if not, write to
# the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 


# ABOUT THE CODE:
# This code was intended as prototyping code. It turned out to become the whole game. We use
# this python version as our alpha release. Bugs will be fixed, but in the mean time the game
# will be ported to c++/sdl. Our beta release will be c++/sdl and from that point this python
# version will no longer be supported.
# This code lacks a good structure and comments.


import pygame
from pygame.locals import *
import math
import os
import sys
from random import randint

from settings import *
from general import *
from player import *
from planet import *
from particle import *
from menu import *
		
class Blackhole(object):
	softspace = 0
	def write(self, text):
		pass

class Game:
	
	particle_image = None
	particle_image_rect = None
	
	pygame.font.init()
	Settings.font = pygame.font.Font("data/FreeSansBold.ttf", 14)
	Settings.menu_font = pygame.font.Font("data/FreeSansBold.ttf", Settings.MENU_FONT_SIZE)
	Settings.round_font = pygame.font.Font("data/FreeSansBold.ttf", 100)
	
	def __init__(self):		
		pygame.display.init()
		
		self.clock = pygame.time.Clock()
		
		self.screen = pygame.display.set_mode((800, 600))
		icon, rect = load_image("data/icon64x64.png", (0,0,0))
		pygame.display.set_icon(icon)
		pygame.display.set_caption('Slingshot')
		
		Settings.particle_image10, Settings.particle_image10_rect = load_image("data/explosion-10.png", (0,0,0))
		Settings.particle_image5, Settings.particle_image5_rect = load_image("data/explosion-5.png", (0,0,0))
		
		Settings.menu_background, Settings.menu_rect = load_image("data/menu.png", (0,0,0))
		Settings.box, rect = load_image("data/box.png", (0,0,0))
		Settings.tick, rect = load_image("data/tick.png", (0,0,0))
		Settings.tick_inactive, rect = load_image("data/tick_inactive.png", (0,0,0))
		
		self.trail_screen = pygame.Surface(self.screen.get_size())
		self.trail_screen = self.trail_screen.convert()
		self.trail_screen.set_colorkey((0,0,0))
		self.trail_screen.set_alpha(125)
		
		self.planet_screen = pygame.Surface(self.screen.get_size())
		self.planet_screen = self.trail_screen.convert()
		self.planet_screen.set_colorkey((0,0,0))
		
		self.dim_screen = pygame.Surface(self.screen.get_size())
		self.dim_screen.set_alpha(175)
		self.dim_screen = self.dim_screen.convert_alpha()
		#self.dim_screen.fill((0,0,0))
		
		self.background, r = load_image("data/backdrop.png")
		
		self.players = (Dummy(), Player(1), Player(2))
		self.playersprites = pygame.sprite.RenderPlain((self.players[1], self.players[2]))
		self.missile = Missile(self.trail_screen)
		self.missilesprite = pygame.sprite.RenderPlain((self.missile))
		
		self.load_settings()
		
		#self.fixed_power = Settings.FIXED_POWER
		#self.bounce = Settings.BOUNCE
		#self.invisible = Settings.INVISIBLE
		#self.random = Settings.RANDOM
		#self.timeout = Settings.MAX_FLIGHT
		
		#self.max_planets = Settings.MAX_PLANETS
		#self.max_rounds = Settings.MAX_ROUNDS
		
		self.main_menu = Menu("Menu")
		self.main_menu.add("Back to game")
		self.main_menu.add("New game")
		self.main_menu.add("Settings")
		self.main_menu.add("Help")
		self.main_menu.add("Quit")
		
		self.confirm_menu1 = Confirm("Starting a new game", "will apply new settings", "and reset the scores")
		self.confirm_menu1.add("Yes")
		self.confirm_menu1.add("No")
		
		self.confirm_menu2 = Confirm("Starting a new game", "will reset the scores")
		self.confirm_menu2.add("Yes")
		self.confirm_menu2.add("No")
		
		self.apply_menu = Confirm("This will start a", "new game and reset", "the scores")
		self.apply_menu.add("Yes")
		self.apply_menu.add("No")
		
		self.settings_menu = Menu("Settings")
		self.settings_menu.add("Back")
		self.settings_menu.add("Game style")
		self.settings_menu.add("Game options")
		self.settings_menu.add("Apply settings")
		self.settings_menu.add("Graphics")
		
		
		self.style_menu = Menu("Game style")
		self.style_menu.add("Back")
		self.style_menu.addoption("Random", self.random)
		self.style_menu.addoption("Fixed power", self.fixed_power, not self.random)
		self.style_menu.addoption("Bounce", self.bounce, not self.random)
		self.style_menu.addoption("Invisible planets", self.invisible, not self.random)
		
		self.mode_menu = Menu("Game options")
		self.mode_menu.add("Back")
		self.mode_menu.add("Max number of planets")
		self.mode_menu.add("Number of rounds")
		self.mode_menu.add("Shot timeout")
		
		self.timeout_menu = Numeric("Shot timeout", self.timeout, 250, 2000, 500)
		
		self.graphics_menu = Menu("Graphics")
		self.graphics_menu.add("Particles")
		
		self.planet_menu = Numeric("Maximum number of planets", self.max_planets, 1, 8, 2)
		
		self.particles_menu = Menu("Particle")
		self.particles_menu.add("Back")
		self.particles_menu.add("On")
		self.particles_menu.add("Off")
		
		self.rounds_menu = Numeric("Number of rounds", self.max_rounds, 5, 100, 0, "Infinite")
		
		self.help_menu = Help()
		
		self.welcome_menu = Welcome()
		
		self.menu = self.welcome_menu
		
		self.q = False
		
		self.message = ""
		self.score_message = ""
		
		self.started = False
		
		self.game_init()
		
	def game_init(self):
		self.new_game()
		self.round_init()
		self.bounce_count = 255
		self.bounce_count_inc = 7
		
	def settings_changed(self):
		result = False
		
		if Settings.MAX_PLANETS != self.max_planets:
			result = True
		if Settings.MAX_FLIGHT != self.timeout:
			result = True
		if Settings.BOUNCE != self.bounce:
			result = True
		if Settings.INVISIBLE != self.invisible:
			result = True
		if Settings.FIXED_POWER != self.fixed_power:
			result = True
		if Settings.MAX_ROUNDS != self.max_rounds:
			result = True
		if Settings.RANDOM != self.random:
			result = True
		
		return result
		
	def new_game(self):
		Settings.MAX_PLANETS = self.max_planets
		Settings.BOUNCE = self.bounce
		Settings.INVISIBLE = self.invisible
		Settings.FIXED_POWER = self.fixed_power
		Settings.MAX_ROUNDS = self.max_rounds
		Settings.RANDOM = self.random
		Settings.MAX_FLIGHT = self.timeout
		
		self.player = randint(1,2)
		
		self.round = 0
		self.players[1].reset_score()
		self.players[2].reset_score()	
		self.game_over = False	
		
	def round_init(self):
		pygame.key.set_repeat(Settings.KEY_DELAY, Settings.KEY_REPEAT)
		
		if self.round == Settings.MAX_ROUNDS:
			self.new_game()
			
		if Settings.RANDOM:
			Settings.BOUNCE = (randint(0,1) == 1)
			Settings.FIXED_POWER = (randint(0,1) == 1)
			Settings.INVISIBLE = (randint(0,1) == 1)
		
		self.round_over = False
		
		self.players[1].init()
		self.players[2].init()
		
		self.missile.flight = 0
		
		self.firing = 0
		self.particlesystem = pygame.sprite.RenderPlain()
		
		self.planetsprites = self.create_planets()
		
		self.trail_screen.fill((0, 0, 0))
		
		self.round += 1
		
		if self.players[1].score < self.players[2].score:
			self.player = 1
		elif self.players[2].score < self.players[1].score:
			self.player = 2
		
		self.show_round = 100
		if Settings.INVISIBLE:
			self.show_planets = 100
		else:
			self.show_planets = 0
		
	def toggle_menu(self):
		if self.menu == None:
			self.menu = self.main_menu
		elif self.menu == self.main_menu:
			self.menu = None
		elif self.menu == self.particles_menu:
			self.menu = self.graphics_menu
		elif self.menu == self.rounds_menu:
			self.menu = self.mode_menu
		elif self.menu == self.planet_menu:
			self.menu = self.mode_menu
		elif self.menu == self.mode_menu:
			self.menu = self.settings_menu
		elif self.menu == self.style_menu:
			self.menu = self.settings_menu
		elif self.menu == self.timeout_menu:
			self.menu = self.mode_menu
		elif self.menu == self.rounds_menu:
			self.menu = self.settings_menu
		else:
			self.menu = self.main_menu
			
#		if self.menu == self.main_menu:
#			self.menu.reset()
		if self.menu != None:
			self.menu.reset()
			
		if self.menu == None:
			pygame.key.set_repeat(Settings.KEY_DELAY, Settings.KEY_REPEAT)
			self.started = True
		else:
			pygame.key.set_repeat()
		
	def create_particlesystem(self, pos, n, size):
		if Settings.PARTICLES:
			if Settings.BOUNCE:
				nn = n / 2
			else:
				nn = n
			for i in range(nn):
				self.particlesystem.add(Particle(pos, size))
		
	def create_planets(self):
		result = pygame.sprite.RenderPlain()
		
		n = randint(2, Settings.MAX_PLANETS)
		for i in range(n):
			result.add(Planet(result, self.background))
			
		return result
	
	def change_angle(self, a):
		self.players[self.player].change_angle(a)
	
	def change_power(self, p):
		self.players[self.player].change_power(p)
	
	def fire(self):
		if self.round_over:
			self.round_init()
		elif not self.firing:
			self.missile.launch(self.players[self.player])
			self.players[self.player].attempts += 1
			self.last = self.player
			self.player = 0
			self.firing = 1
			pygame.key.set_repeat()
		
	def draw_zoom(self):
		normal_screen = pygame.Surface((800, 600))
		normal_screen.set_colorkey((0,0,0))
		normal_screen.convert_alpha()
		self.playersprites.draw(normal_screen)
		if not Settings.INVISIBLE:
			self.planetsprites.draw(normal_screen)
		
		zoom_screen = pygame.Surface((600, 450))
		zoom_screen.set_colorkey((0,0,0))
		zoom_screen.convert_alpha()
		
		background = pygame.transform.scale(self.background, (600,450))
		zoom_screen.blit(self.background, (0,0))
		normal_screen = pygame.transform.scale(normal_screen, (200,150))
		zoom_screen.blit(normal_screen, (200,150))
		
		missilesprite = self.missile.get_image()
		missilesprite = pygame.transform.scale(missilesprite, (missilesprite.get_size()[0] / 3, missilesprite.get_size()[1] / 3))
		pos = self.missile.get_pos()
		pos = (200 + pos[0] / 4 - missilesprite.get_width() / 2, 150 + pos[1] / 4- missilesprite.get_height() / 2)
		zoom_screen.blit(missilesprite, pos)
		
		pygame.draw.rect(zoom_screen, (255,255,255), pygame.Rect(0, 0, 600, 450), 1)
		pygame.draw.rect(zoom_screen, (150,150,150), pygame.Rect(200, 150, 200, 150), 1)
		self.screen.blit(self.dim_screen, (0,0))
		self.screen.blit(zoom_screen, (100, 75))
				
	def draw(self):
		self.screen.blit(self.background, (0, 0))
		
		if Settings.BOUNCE:
			pygame.draw.rect(self.screen, (self.bounce_count, 0, 0), pygame.Rect(0, 0, 800, 600), 1)
		
		show_planets = False
		if not Settings.INVISIBLE:
			show_planets = True
		else:
			if self.round_over:
				if self.show_planets > 0:
					for p in self.planetsprites:
						p.fade(self.show_planets)
					self.planetsprites.draw(self.screen)
					self.show_planets -= 1
				else:
					show_planets = True
		if show_planets:
			self.planetsprites.draw(self.screen)
		self.screen.blit(self.trail_screen, (0,0))
		self.playersprites.draw(self.screen)
#		self.players[1].draw(self.screen)
#		self.players[2].draw(self.screen)
#		print self.particlesystem
		if Settings.PARTICLES:
			self.particlesystem.draw(self.screen)
		if self.firing:
			if self.missile.visible():
				self.missilesprite.draw(self.screen)
#		print self.planetsprites
		if self.firing:
			if not self.missile.visible():
				self.draw_zoom()
		self.players[1].draw_status(self.screen)
		self.players[2].draw_status(self.screen)
		if not self.round_over:
			self.players[self.player].draw_info(self.screen)
			self.players[self.player].draw_line(self.screen)
		else:
			if self.show_round > 30:
				txt = Settings.round_font.render("Game Over", 1, (255,255,255))
				tmp = pygame.Surface(txt.get_size())
				tmp = tmp.convert_alpha()
				tmp.blit(txt, (0,0))
				tmp = tmp.convert()
				tmp.set_alpha(2 * self.show_round - 60)
				tmp.set_colorkey((0,0,0))
				tmp = tmp.convert_alpha()
				rect = tmp.get_rect()
				s = (100 - self.show_round) * rect.h / 15
				tmp = pygame.transform.scale(tmp, (rect.w / rect.h * s, s ))
				rect = tmp.get_rect()
				rect.center = (399,299)
				self.screen.blit(tmp, rect.topleft)
				self.show_round /= 1.04
			elif self.show_planets <= 0:
				dim = pygame.Surface(self.end_round_msg.get_size())
				dim.set_alpha(175)
				dim = dim.convert_alpha()
				
				rect = self.end_round_msg.get_rect()
				rect.center = (399,299)
				
				self.screen.blit(dim, rect.topleft)
				self.screen.blit(self.end_round_msg, rect.topleft)
		
		if self.firing:
			self.missile.draw_status(self.screen)
		elif self.started:
			if Settings.MAX_ROUNDS > 0:
				txt = Settings.font.render("Round %d of %d" %(self.round, Settings.MAX_ROUNDS), 1, (255,255,255))
			else:
				txt = Settings.font.render("Round %d" %(self.round), 1, (255,255,255))
			rect = txt.get_rect()
			rect.midbottom = (399, 594)
			self.screen.blit(txt, rect.topleft)
			
		if self.started and not self.game_over:
			if self.show_round > 30:
				txt = Settings.round_font.render("Round %d" %(self.round), 1, (255,255,255))
				tmp = pygame.Surface(txt.get_size())
				tmp = tmp.convert_alpha()
				tmp.blit(txt, (0,0))
				tmp = tmp.convert()
				tmp.set_alpha(2 * self.show_round - 60)
				tmp.set_colorkey((0,0,0))
				tmp = tmp.convert_alpha()
				rect = tmp.get_rect()
				s = (100 - self.show_round) * rect.h / 25
				tmp = pygame.transform.scale(tmp, (rect.w / rect.h * s, s ))
				rect = tmp.get_rect()
				rect.center = (399,299)
				self.screen.blit(tmp, rect.topleft)
				self.show_round /= 1.04
			
		if not self.menu == None:
			if self.menu.dim:
				self.screen.blit(self.dim_screen, (0,0))
			img = self.menu.draw()
			rect = img.get_rect()
			rect.center = (399,299)
			self.screen.blit(img, rect.topleft)
			
		pygame.display.flip()
			
	def update_particles(self):
		if Settings.PARTICLES:
			for p in self.particlesystem:
	#			print p.get_pos()
				if p.update(self.planetsprites) == 0 or p.flight < 0:
					if p.flight >= 0 and p.in_range():
						if p.get_size() == 10:
							self.create_particlesystem(p.get_impact_pos(), Settings.n_PARTICLES_5, 5)
	#				print "removing: ", p.get_pos()
					self.particlesystem.remove(p)
				if p.flight > Settings.MAX_FLIGHT:
					self.particlesystem.remove(p)
	
	def end_shot(self):
		pygame.event.clear()
		self.player = 3 - self.last
		if self.menu == None:
			pygame.key.set_repeat(Settings.KEY_DELAY,Settings.KEY_REPEAT)
		self.firing = 0
		
	def menu_action(self):
		c = self.menu.get_choice()
		if self.menu == self.planet_menu:
			if c >= 0:
				self.max_planets = c
				self.toggle_menu()
		if self.menu == self.rounds_menu:
			if c >= 0:
				self.max_rounds = c
				self.toggle_menu()
		if self.menu == self.timeout_menu:
			if c >= 0:
				self.timeout = c
				self.toggle_menu()
		if c == "Quit":
			self.q = True
		elif c == "Back":
			self.toggle_menu()
		elif c == "Start":
			self.started = True
			self.menu = None
		elif c == "Back to game":
			self.toggle_menu()
		elif c == "Apply settings":
			self.menu = self.apply_menu
		elif c == "New game":
			if self.settings_changed():
				self.menu = self.confirm_menu1
			else:
				self.menu = self.confirm_menu2
		elif c == "Number of rounds":
			self.menu = self.rounds_menu
		elif c == "Shot timeout":
			self.menu = self.timeout_menu
		elif c == "Game style":
			self.menu = self.style_menu
		elif c == "Random":
			self.random = not self.random
			self.style_menu.change_active("Bounce", not self.random)
			self.style_menu.change_active("Invisible planets", not self.random)
			self.style_menu.change_active("Fixed power", not self.random)
		elif c == "Help":
			self.menu = self.help_menu
		elif c == "Yes":
			self.menu = None
			self.save_settings()
			self.game_init()
		elif c == "No":
			self.toggle_menu()
		elif c == "Settings":
			self.menu = self.settings_menu
		elif c == "Game options":
			self.menu = self.mode_menu
		elif c == "Graphics":
			self.menu = self.graphics_menu
		elif c == "Shot timeout":
			self.menu = self.timeout_menu
		elif c == "Fixed power":
			self.fixed_power = not self.fixed_power
		elif c == "Bounce":
			self.bounce = not self.bounce
		elif c == "Invisible planets":
			self.invisible = not self.invisible
		elif c == "Max number of planets":
			self.menu = self.planet_menu
		elif c == "Particles":
			self.menu = self.particles_menu
		elif c == "On":
			Settings.PARTICLES = True
			self.toggle_menu()
		elif c == "Off":
			Settings.PARTICLES = False
			self.toggle_menu()
		
	def update(self):
		self.update_particles()
		if self.firing:
			self.firing = self.missile.update(self.planetsprites, self.players)
			if self.missile.flight < 0 and not self.missile.visible():
				self.firing = 0
			if not self.firing:
				if self.missile.visible():
					self.create_particlesystem(self.missile.get_impact_pos(), Settings.n_PARTICLES_10, 10)
				self.end_shot()
		if not self.menu == None:
			self.menu_action()
		if self.players[1].shot or self.players[2].shot:
			if self.players[1].shot:
				self.players[1].update_explosion()
			else:
				self.players[2].update_explosion()
			pygame.key.set_repeat()
			if not self.round_over:
				self.end_round()
		if self.menu == None:
			self.started = True
			
		self.bounce_count += self.bounce_count_inc
		if self.bounce_count > 255 or self.bounce_count < 125:
			self.bounce_count_inc *= -1
			self.bounce_count += 2 * self.bounce_count_inc
				
	def end_round(self):
		self.round_over = True
		
		if self.round == Settings.MAX_ROUNDS:
			offset1 = 50
		else:
			offset1 = 0
		
		power_penalty = self.missile.get_score()
		for i in range(1, 3):
			if self.players[i].shot:
				if self.player == 3 - i:
					message = "Player %d killed self" %(i)
					score = Settings.SELFHIT
					score_message = "%d deducted from score" %(score)
					self.players[i].add_score(-score)
					killed_self = True
				else:
					message = "Player %d killed player %d" %((3 - i), i)
					if self.players[3 - i].attempts == 1:
						bonus = Settings.QUICKSCORE1
					elif self.players[3 - i].attempts == 2:
						bonus = Settings.QUICKSCORE2
					elif self.players[3 - i].attempts == 3:
						bonus = Settings.QUICKSCORE3
					else:
						bonus = 0
					killed_self = False
					score = power_penalty + bonus + Settings.HITSCORE
					score_message = "%d added to score" %(score)
					self.players[3 - i].add_score(score)
				
				if not killed_self:
					offset = 40
				else:
					offset = 0
					
				if self.round == Settings.MAX_ROUNDS:
					offset2 = 40
				else:
					offset2 = 0
									
				self.end_round_msg = pygame.Surface((450,190 + offset + offset1 + offset2))
				self.end_round_msg.set_colorkey((0,0,0))
				self.end_round_msg.fill((0,0,0))
				
				if self.round == Settings.MAX_ROUNDS:
					msg = Settings.menu_font.render("Game over", 1, (255,255,255))
					rect = msg.get_rect()
					rect.midtop = (224, 28)
					self.end_round_msg.blit(msg, rect.topleft)
				
				msg = Settings.font.render(message, 1, (255,255,255))
				rect = msg.get_rect()
				rect.midtop = (224,28 + offset1)
				self.end_round_msg.blit(msg, rect.topleft)
				
				if not killed_self:
					msg = Settings.font.render("Hit opponent:", 1, (255,255,255))
				else:
					msg = Settings.font.render("Hit self:", 1, (255,255,255))
				rect = msg.get_rect()
				rect.topleft = (50,65 + offset1)
				self.end_round_msg.blit(msg, rect.topleft)
				
				if not killed_self:
					msg = Settings.font.render("%d" %(Settings.HITSCORE), 1, (255,255,255))
				else:
					msg = Settings.font.render("%d" %(Settings.SELFHIT), 1, (255,255,255))
				rect = msg.get_rect()
				rect.topright = (399,65 + offset1)
				self.end_round_msg.blit(msg, rect.topleft)
				
				if not killed_self:
					msg = Settings.font.render("Quickhit bonus:", 1, (255,255,255))
					rect = msg.get_rect()
					rect.topleft = (50,85 + offset1)
					self.end_round_msg.blit(msg, rect.topleft)
					
					msg = Settings.font.render("%d" %(bonus), 1, (255,255,255))
					rect = msg.get_rect()
					rect.topright = (399,85 + offset1)
					self.end_round_msg.blit(msg, rect.topleft)
				
					msg = Settings.font.render("Power penalty:", 1, (255,255,255))
					rect = msg.get_rect()
					rect.topleft = (50,105 + offset1)
					self.end_round_msg.blit(msg, rect.topleft)
				
					msg = Settings.font.render("%d" %(power_penalty), 1, (255,255,255))
					rect = msg.get_rect()
					rect.topright = (399,105 + offset1)
					self.end_round_msg.blit(msg, rect.topleft)
					
				msg = Settings.font.render(score_message, 1, (255,255,255))
				rect = msg.get_rect()
				rect.midtop = (224, 100 + offset + offset1)
				self.end_round_msg.blit(msg, rect.topleft)
				
				if self.round == Settings.MAX_ROUNDS:
					self.show_round = 100
					self.game_over = True
					if self.players[1].score > self.players[2].score:
						winner = 1
					elif self.players[2].score > self.players[1].score:
						winner = 2
					else:
						winner = 0
					Settings.font.set_bold(True)
					if winner != 0:
						msg = Settings.font.render("Player %d has won the game" %(winner), 1, (255,255,255))
					else:
						msg = Settings.font.render("The game has ended in a tie", 1, (255,255,255))
					Settings.font.set_bold(False)
					rect = msg.get_rect()
					rect.midtop = (224, 140 + offset + offset1)
					self.end_round_msg.blit(msg, rect.topleft)
								
				if self.round < 10:
					msg = Settings.font.render("Press fire for a new round or escape for the menu", 1, (255,255,255))
				else:
					msg = Settings.font.render("Press fire for a new game or escape for the menu", 1, (255,255,255))
				rect = msg.get_rect()
				rect.midtop = (224, 140 + offset + offset1 + offset2)
				self.end_round_msg.blit(msg, rect.topleft)
				
				pygame.draw.rect(self.end_round_msg, (150,150,150), self.end_round_msg.get_rect(), 1)

	
	def run(self):
		while not self.q:
			self.clock.tick(Settings.FPS)
#			print clock.get_fps()
			
			for event in pygame.event.get(): 
				if event.type == QUIT: 
					self.q = True
				elif event.type == KEYDOWN:
					if event.key == K_ESCAPE:
						self.toggle_menu()
					
					if self.menu == None:
						if event.mod == 4160 or event.mod == 64 or event.mod == 4224:
							p = 1
							a = 0.25
						elif event.mod == 4097 or event.mod == 1 or event.mod == 4098:
							p = 25
							a = 5
						elif event.mod == 4352 or event.mod == 20480 or event.mod == 4608:
							p = 0.2
							a = 0.05
						else:
							p = 10
							a = 2
						
						if not self.round_over:
							if event.key == K_UP:
								self.change_power(p)
							elif event.key == K_DOWN:
								self.change_power(-p)
							elif event.key == K_LEFT:
								self.change_angle(-a)
							elif event.key == K_RIGHT:
								self.change_angle(a)
						if event.key == 13 or event.key == 32:
							self.fire()
					else:
						if event.key == K_UP:
							self.menu.up()
						elif event.key == K_DOWN:
							self.menu.down()
						elif event.key == K_LEFT:
							self.menu.left()
						elif event.key == K_RIGHT:
							self.menu.right()
						elif event.key == 13 or event.key == 32:
							self.menu.select()
			
			self.update()
			self.draw()
			
		self.save_settings()
	

	def load_settings(self):
		
		self.bounce = Settings.BOUNCE
		self.fixed_power = Settings.FIXED_POWER
		self.invisible = Settings.INVISIBLE
		self.random = Settings.RANDOM
		self.max_planets = Settings.MAX_PLANETS
		self.timeout = Settings.MAX_FLIGHT
		self.max_rounds = Settings.MAX_ROUNDS
		
		path = os.path.expanduser("~") + "/.slingshot/settings"
		
		if os.path.exists(path):
			f=open(path, 'r')
			lines = f.readlines()
			for l in lines:
				tokens = l.split()
				if tokens[0] == "Bounce:":
					if tokens[1] == "1":
						self.bounce = True
				if tokens[0] == "Fixed_Power:":
					if tokens[1] == "1":
						self.fixed_power = True
				elif tokens[0] == "Particles:":
					if tokens[1] == "1":
						Settings.PARTICLES = True
				elif tokens[0] == "Random:":
					if tokens[1] == "1":
						self.random = True
				elif tokens[0] == "Invisible:":
					if tokens[1] == "1":
						self.invisible = True
				elif tokens[0] == "Max_Planets:":
					self.max_planets = int(tokens[1])
				elif tokens[0] == "Timeout:":
					self.timeout = int(tokens[1])
				elif tokens[0] == "Rounds:":
					self.max_rounds = int(tokens[1])
			f.close()
			
	def save_settings(self):
		path = os.path.expanduser("~") + "/.slingshot"
		if not os.path.exists(path):
			os.mkdir(path)
		path += "/settings"
		f = file(path, 'wt')
		if self.bounce:
			f.write("Bounce: 1\n")
		else:
			f.write("Bounce: 0\n")
		if self.fixed_power:
			f.write("Fixed_Power: 1\n")
		else:
			f.write("Fixed_Power: 0\n")
		if self.invisible:
			f.write("Invisible: 1\n")
		else:
			f.write("Invisible: 0\n")
		if self.random:
			f.write("Random: 1\n")
		else:
			f.write("Random: 0\n")
		if Settings.PARTICLES:
			f.write("Particles: 1\n")
		else:
			f.write("Particles: 0\n")
		f.write("Max_Planets: %d\n" %(self.max_planets))
		f.write("Timeout: %d\n" %(self.timeout))
		f.write("Rounds: %d\n" %(self.max_rounds))
		f.close()
			

def main():
    
	#sys.stdout = Blackhole()
	#sys.stderr = Blackhole()
	path = os.path.expanduser("~") + "/.slingshot"
	if not os.path.exists(path):
		os.mkdir(path)
	path += "/logfile.txt"
	sys.stderr = open(path,"w")
	sys.stdout = sys.stderr
	game = Game()
	game.run()

if __name__ == '__main__': main()
