from physics import Physics
from worldgui import WorldGui
from player import Player
import pygame
from pygame.constants import *
import time
from tiles import Tiles
import mapgen
import numpy.random as rn
import math
from settings import *
from encounter import Encounter
import random
from constants import *
from items import *
import names

class World:
	def __init__(self, game, type, physics = None, world = None, encounter = None):
		self.type = type

		if world:
			self.world = world

		if encounter:
			self.currentEncounter = encounter

		self.scrollerWorld = None

		self.game = game

		if not physics:
			self.physics = Physics()
		else:
			self.physics = physics

		self.surface = pygame.Surface(self.game.screen.get_size()).convert()

		self.player = Player(self)
		self.clock = pygame.time.Clock()

		if self.type == "map":
			self.score = 0
			self.found_artifacts = []

			self.generateWorld()

			self.fog = pygame.Surface(self.tiles.tSurf.get_size(), pygame.SRCALPHA).convert_alpha()
			self.fog.fill((0,0,0,255))

		elif self.type == "scroller":
			self.encounter = Encounter(self)
			self.powerups = []
			self.player.setEntrance()
			self.player.generateMapGroup()

	def generateWorld(self):
		self.bgcolor = (0,0,0)
		self.surface.fill(self.bgcolor)
		imgLoad = pygame.image.load("loadscreen.png")
		titlePlate = pygame.image.load("titleplate.png")
		self.surface.blit(titlePlate,(self.game.screen.get_size()[0]/2-192, self.game.screen.get_size()[1]/2-192))
		self.surface.blit(imgLoad,(self.game.screen.get_size()[0]/2-160, self.game.screen.get_size()[1]/2-64))
		self.game.screen.blit(self.surface, (0,0))
		pygame.display.flip()

		self.tiles = Tiles(self.game.screen.get_size(), self.physics)
		self.tileX = 0
		self.tileY = 0
		self.tileW, self.tileH =  self.tiles.tSurf.get_size()
		self.encounters = mapgen.gen_encounters(
				self.tiles.tMap,
				[(rn.randint(0, 9), x) for x in       range(settings_encounters['amount'])])
		for i, enc in enumerate(self.encounters):
			x1, y1 = enc[1]
			for j, enc2 in enumerate(self.encounters):
				if i == j: continue
				x2, y2 = enc2[1]
				distance  = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
				if distance > 10: continue
				nyenc = mapgen.gen_encounters(
						self.tiles.tMap, [(rn.randint(0, 9), j)])
				if len(nyenc) > 0: self.encounters[j] = nyenc[0]

		for enc in self.encounters:
			self.tiles.addEncounter(enc[1])

		for i, enc in enumerate(self.encounters):
			p = Physics()
			item = names.items[random.randint(0, len(names.items) - 1)]
			self.encounters[i] = enc + (p, self.generateEncounterInfo(p,item),
					names.names[random.randint(0, len(names.names) - 1)],item)

		self.gui = WorldGui(self)

	def generateEncounterInfo(self, physics, item):
		hazard = 0
		info1 = ""
		info2 = "Threat Level: "
		info3 = "Climate: Frigid"
		info4 = ""

		if physics.gravity_orientation != ORIENTATION_DOWN:
			hazard += 1

		if physics.gravity > 15:
			hazard += 1

		if physics.windVelocity > 3:
			hazard += physics.windVelocity - 3

		if physics.windDirection == physics.gravity_orientation:
			hazard += 1
			if physics.maximumVelocity < physics.windVelocity + physics.gravity:
				hazard += 1

		if hazard == 0:
			info4 += "No danger"
		elif hazard == 1:
			info4 += "No danger"
		elif hazard == 2:
			info4 += "Light threat"
		elif hazard == 3:
			info4 += "Normal threat"
		elif hazard == 4:
			info4 += "Severe threat"
		elif hazard == 5:
			info4 += "High threat"
		elif hazard == 6:
			info4 += "Extreme threat"
		elif hazard >= 7:
			info4 += "Lethal"

		return "\n".join([info1, info2, info3, info4])

	def stop(self):
		self.isRunning = False
		self.game.gamestack.pop()

		if self.type == "map":
			f = open("highscore", "a")
			print >>f, self.score
			print >>f, self.found_artifacts
			f.close()

	def acceptEncounter(self):
		x = int(self.tileX / 32.0 + self.player.position.x / 32.0 + 0.5)
		y = int(self.tileY / 32.0 + self.player.position.y / 32.0 + 0.5)
		for i in self.encounters:
			if i[1] == (x, y):
			#	print "Accept encounter:", i[0]
				self.scrollerWorld = World(self.game, "scroller", i[2], self, i)
				self.game.gamestack.push(self.scrollerWorld.run, [])
				self.isRunning = False

	def handleInput(self):
		for event in pygame.event.get():
			if event.type == QUIT:
				self.stop()
				return
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					self.stop()
					return

			if self.player.handleEvent(event): continue

			if self.type == "map":
				if self.gui.handleEvent(event): continue


	def run(self):
		self.isRunning = True

		frames = 0
		lastFrame = time.time()
		while self.isRunning:
			self.clock.tick(30)

			frames += 1
			if time.time() - lastFrame > 1:
				#print "FPS:", frames
				frames = 0
				lastFrame = time.time()

			self.handleInput()
			self.player.updatePosition()

			self.surface.fill((0,0,0,0))
			w, h = self.game.screen.get_size()

			if self.type == "map":
				pygame.draw.circle(self.fog, (0,0,0,0),
						(self.player.position.x + self.tileX, self.player.position.y + self.tileY), 200)
				self.surface.blit(self.tiles.getMap(w, h), (0,0))
				self.surface.blit(self.fog, (0,0), area = (self.tileX, self.tileY, w, h))
				
			elif self.type == "scroller":
				self.encounter.draw(self.surface)

			self.player.draw(self.surface)
			if self.type == "map":
				self.gui.draw(self.surface)
			self.game.screen.blit(self.surface, (0,0))
			pygame.display.flip()

