import pygame
from pygame.constants import *
from constants import *
from settings import *
import names
import time
import random
from items import *

class Position:
	def __init__(self, x, y):
		self.x = x
		self.y = y

	def getXY(self):
		return (self.x, self.y)

class Player:
	def __init__(self, world):
		self.world = world

		self.sizeX, self.sizeY = 32, 32
		if self.world.type == "map":
			self.sizeY = 32
			self.position = Position(self.world.game.screen.get_width() / 2, self.world.game.screen.get_height() / 2)
		else:
			self.sizeY = 64

		self.orientation = ORIENTATION_DOWN

		self.velocity = Position(0,0)
		self.maximumVelocity = self.world.physics.maximumVelocity

		self.upPressed = False
		self.downPressed = False
		self.leftPressed = False
		self.rightPressed = False
		self.direction = 2

		self.movementSpeed = self.world.physics.movementSpeed
		self.speedX=0
		self.speedY=0

		self.color = (255,255,0)

		self.lastUpdate = time.time()
		self.airTime = time.time()

		if self.world.type == "scroller":
			self.powerups = []


	def generateMapGroup(self):
		self.mapGroup = pygame.sprite.Group()
		for x, row in enumerate(self.world.encounter.tiles.tMap):
			for y, value in enumerate(row):
				if value == 0 or value == 1: continue
				s = pygame.sprite.Sprite()
				s.rect = pygame.Rect(x * 32, y * 32, 32, 32)
				s.mask = pygame.mask.Mask((32, 32))
				s.mask.fill()
				self.mapGroup.add(s)

	def setEntrance(self):
		self.entrance = 0
		screenW, screenH = self.world.game.screen.get_size()
		entranceList = self.world.encounter.tiles.tMap[2]
		for y,value in enumerate(entranceList):
			if value == 0:
				#print "Found it!"
				self.entrance = y

		self.world.encounter.tileX, self.world.encounter.tileY = self.world.encounter.tiles.setXY(0, (self.entrance-15)*32)
		self.position = Position(2*32, (self.entrance * 32) - self.world.encounter.tileY - 32)

	def updateDirection(self):
		if self.speedY> 0:
			if self.speedX > 0: self.direction = 3
			elif self.speedX < 0: self.direction = 5
			else: self.direction = 4
		elif self.speedY < 0:
			if self.speedX > 0: self.direction = 1
			elif self.speedX < 0: self.direction = 7
			else: self.direction = 0
		elif self.speedX > 0:
			if self.speedY > 0: self.direction = 3
			elif self.speedY < 0: self.direction = 1
			else: self.direction = 2
		elif self.speedX < 0:
			if self.speedY > 0: self.direction = 5
			elif self.speedY < 0: self.direction = 7
			else: self.direction = self.direction = 6

	def setColor(self, color):
		self.color = color

	def draw(self, surface):
		self.updateDirection()
		if self.world.type == "map":
			pSpMap = self.world.tiles.getPlayerSprite(self.direction)
			x = int(self.world.tileX / 32.0 + self.position.x / 32.0 + 0.5)
			y = int(self.world.tileY / 32.0 + self.position.y / 32.0 + 0.5)
			if x < self.world.physics.light:
				pSpMap.fill((255 - 40 * (3 - 0), 255 - 40 * (3 - 0),
					255 - 40 * (3 - 0)), special_flags=pygame.BLEND_RGBA_MULT)
			elif x - self.world.physics.light > self.world.tiles.w - 1:
				pSpMap.fill((255 - 40 * (3 - 0), 255 - 40 * (3 - 0),
					255 - 40 * (3 - 0)), special_flags=pygame.BLEND_RGBA_MULT)
			else:
				pSpMap.fill((255 - 40 * (3 - \
						self.world.tiles.light[x - self.world.physics.light, y]),
						255 - 40 * (3 - \
								self.world.tiles.light[x - self.world.physics.light, y]),
						255 - 40 * (3 - \
								self.world.tiles.light[x - self.world.physics.light, y])),
						special_flags=pygame.BLEND_RGBA_MULT)
			surface.blit(pSpMap, self.position.getXY())
		else:
			surface.blit(self.world.encounter.tiles.getPlayerSprite(self.direction),
					self.position.getXY())

	def setPosition(self, x, y):
		self.position = (x, y)

	def checkCollision(self, x, y):
		playerSprite = pygame.sprite.Sprite()
		playerSprite.rect = pygame.Rect(x + self.world.encounter.tileX, y + self.world.encounter.tileY, 32, 64)
		playerSprite.image = self.world.encounter.tiles.getPlayerSprite(self.direction)
		playerSprite.mask = pygame.mask.from_surface(playerSprite.image)

		collision = pygame.sprite.spritecollide(playerSprite, self.mapGroup, False, pygame.sprite.collide_mask)
		return not collision == []

	def updatePosition(self):
		w, h = self.world.game.screen.get_size()
		self.speedX = 0
		self.speedY = 0


		if self.world.type == "scroller":
			for i in self.powerups:
				i.doMagic()

		if self.upPressed:
			self.velocity.y -= self.movementSpeed
			if self.world.type == "map":
				self.position.y -= self.movementSpeed
				self.world.tileY -= self.movementSpeed
			self.speedY=-1
		if self.downPressed:
			self.velocity.y += self.movementSpeed
			if self.world.type == "map":
				self.position.y += self.movementSpeed
				self.world.tileY += self.movementSpeed
			self.speedY=1

		if self.leftPressed:
			self.velocity.x -= self.movementSpeed
			if self.world.type == "map":
				self.position.x -= self.movementSpeed
				self.world.tileX -= self.movementSpeed
			self.speedX=-1
		if self.rightPressed:
			self.velocity.x += self.movementSpeed
			if self.world.type == "map":
				self.position.x += self.movementSpeed
				self.world.tileX += self.movementSpeed
			self.speedX=1

		if self.velocity.x < 0:
			self.velocity.x += 1
		elif self.velocity.x > 0:
			self.velocity.x -= 1

		if self.velocity.y < 0:
			self.velocity.y += 1
		elif self.velocity.y > 0:
			self.velocity.y -= 1


		if abs(self.velocity.x) > self.maximumVelocity:
			self.velocity.x = (abs(self.velocity.x)/self.velocity.x) * self.maximumVelocity

		if abs(self.velocity.y) > self.maximumVelocity:
			self.velocity.y = (abs(self.velocity.y)/self.velocity.y) * self.maximumVelocity

		if self.world.type == "map":
			self.world.tileX, self.world.tileY = \
					self.world.tiles.setXY(self.world.tileX, self.world.tileY)

			if self.world.tileX < self.world.tileW - w - self.sizeX - 100:
				if self.position.x > w - self.sizeX - 100: self.position.x = w - self.sizeY - 100
			if self.world.tileX > 100:
				if self.position.x < 100: self.position.x = 100

			if self.world.tileY > 100:
				if self.position.y < 100: self.position.y = 100
			if self.world.tileY < self.world.tileH - h - self.sizeY - 185:
				if self.position.y > h - self.sizeX - 185: self.position.y = h - self.sizeX - 185

			if self.position.y > h - self.sizeX: self.position.y = h - self.sizeX
			if self.position.x > w - self.sizeY: self.position.x = w - self.sizeY
			if self.position.y < 0: self.position.y = 0
			if self.position.x < 0: self.position.x = 0
			if not self.leftPressed and not self.rightPressed: self.speedX = 0
			if not self.upPressed and not self.downPressed: self.speedY = 0

			t =  self.world.tiles.getTileType(self.position.x, self.position.y)
			#print "tile type: [01;3%sm%s[00m" % (t % 7, t)
			if t == 0: self.setColor((255,0,0))
			else: self.setColor((255,255,0))

			x = int(self.world.tileX / 32.0 + self.position.x / 32.0 + 0.5)
			y = int(self.world.tileY / 32.0 + self.position.y / 32.0 + 0.5)

			self.world.gui.setInfoText("")
			self.world.gui.setMiniText("")
			self.world.gui.setHelpText("")
			for i in self.world.encounters:
				if i[1] == (x, y):
					space = 20
					if len(i[5]) > 20:
						for x in range(20):
							if i[5][20-x] == " ":
								space = 20-x
								break
						firstLine = i[5][:space]
						secondLine = i[5][space+1:]
						space2 = 20
						if len(secondLine) > 20:
							for x in range(20):
								if secondLine[20-x] == " ":
									space = 20-x
									break
							thirdLine = secondLine[space2+1:]
							secondLine = secondLine[:space2+1]
							
							self.world.gui.setHelpText("Artifact: \n%s\n%s\n%s" % (firstLine,secondLine,thirdLine))
						else:
							self.world.gui.setHelpText("Artifact: \n%s\n%s" % (firstLine,secondLine))
					else:
						self.world.gui.setHelpText("Artifact: \n %s" % (i[5][:18]))
					self.world.gui.setInfoText("The cavern of %s" % (i[4]))
					self.world.gui.setMiniText(i[3])
					

		else:
			t = self.airTime - time.time()

			newy = self.position.y
			newx = self.position.x

			newx += self.velocity.x
			newy += self.velocity.y

			#Update Gravity
			newx, newy = self.world.physics.getGravity(t,newx,newy)

			#Update Wind
			newx, newy = self.world.physics.getWindEffect(newx,newy)

			if self.checkCollision(newx, newy):
				self.airTime = time.time()
				if self.world.physics.gravity_orientation == ORIENTATION_DOWN or \
						self.world.physics.gravity_orientation == ORIENTATION_UP:
							self.velocity.y = 0
				else:
					self.velocity.x = 0
				newx, newy = self.position.x, self.position.y

			if newy > h - self.sizeY - 50 or newx > w - self.sizeX - 50 or newy < 50 or newx < 50:
				diffX = self.position.x - newx
				diffY = self.position.y - newy

				tx = self.world.encounter.tileX
				ty = self.world.encounter.tileY
				self.world.encounter.tileX, self.world.encounter.tileY = \
					self.world.encounter.tiles.setXY(tx - diffX, ty - diffY)

				if tx != self.world.encounter.tileX or ty != self.world.encounter.tileY:
					if newy > h - self.sizeY - 50:
						newy = h - self.sizeY - 50
					if newx > w - self.sizeX - 50:
						newx = w - self.sizeX - 50
					if newy < 50:
						newy = 50
					if newx < 50:
						newx = 50
				else:
					pass
					#self.world.stop()

			if self.checkCollision(newx, newy):
				self.airTime = time.time()
				if self.world.physics.gravity_orientation == ORIENTATION_DOWN or \
						self.world.physics.gravity_orientation == ORIENTATION_UP:
							self.velocity.y = 0
				else:
					self.velocity.x = 0
				newx, newy = self.position.x, self.position.y

			if settings_encounters['parallax_enable']:
				diffX = self.position.x - newx
				diffY = self.position.y - newy
				self.world.encounter.background1.update(-diffX*0.3)
				self.world.encounter.background2.update(-diffX*0.7)

			#tx = self.world.encounter.tileX - diffX
			#ty = self.world.encounter.tileY - diffY
			#self.world.encounter.tileX, self.world.encounter.tileY = \
			#	self.world.encounter.tiles.setXY(tx, ty)

			self.position.y = newy
			self.position.x = newx

			x = int(self.world.encounter.tileX / 32.0 + self.position.x / 32.0 + 0.5)
			y = int(self.world.encounter.tileY / 32.0 + self.position.y / 32.0 + 0.5)

			for i, (x1, y1) in enumerate(self.world.encounter.flufflist):
				if (x, y) == (x1, y1) or (x, y + 1) == (x1, y1):
					a = ""
					if self.world.encounter.flufftype[i][0] == 0:
						a = "artifact"
					elif self.world.encounter.flufftype[i][0] == 1:
						a = "item"
						continue
					elif self.world.encounter.flufftype[i][0] == 2:
						a = "powerup"
					#print a

					self.world.encounter.tiles.tMap[x1, y1] = 0
					self.world.encounter.tiles.tSurf.blit(
							self.world.encounter.tiles.getTile(35),
							(x1 * 32, y1 * 32))


					if (x1, y1) == self.world.encounter.artifact:
						self.world.world.found_artifacts.append(self.world.currentEncounter[5])
						self.world.encounter.got_item(self.world.currentEncounter[5])
						#print "Artifact"

					elif a == "powerup":
						p = random.choice(availablePowerUps)
						self.powerups.append(p(self))

					self.world.world.score += 10
					self.world.encounter.flufflist.remove((x1,y1))

		self.lastUpdate = time.time()

	def handleEvent(self, event):
		if event.type == KEYDOWN or event.type == KEYUP:
			if event.key == K_w or event.key == K_UP:
				self.upPressed = True if event.type == KEYDOWN else False
				return True
			elif event.key == K_s or event.key == K_DOWN:
				self.downPressed = True if event.type == KEYDOWN else False
				return True
			elif event.key == K_a or event.key == K_LEFT:
				self.leftPressed = True if event.type == KEYDOWN else False
				return True
			elif event.key == K_d or event.key == K_RIGHT:
				self.rightPressed = True if event.type == KEYDOWN else False
				return True

		if event.type == KEYDOWN:
			if event.key == K_SPACE:
				if self.world.type == "scroller":
					#self.world.physics.jump(self)
					return True
			elif event.key == K_RETURN:
				if self.world.type == "map":
					self.world.acceptEncounter()
					return True

		return False
