import os, pygame, random, perlin
from pygame.locals import *

if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'

def load_image(name):
	fullname = os.path.join('data', name)
	try:
		image = pygame.image.load(fullname)
	except pygame.error, message:
		print 'Cannot load image:', fullname
		raise SystemExit, message
	image = image.convert()
	return image

def debugMessage(string):
	print string

class TILE():
	images=[] #Image for 4xnormal, cracked, damaged and broken tile
	strength=[] #How easy it is to break the tile from normal->cracked, cracked->damaged, damaged->broken and broken->destroyed
	lemit=[] #Light emmision and color
	name="" #Tile name
	def __init__(self):
		self.images=[Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32),Rect(0,0,32,32)] #Image for 4xnormal, cracked, damaged and broken tile
		self.strength=[100,100,100,100] #How easy it is to break the tile from normal->cracked, cracked->damaged, damaged->broken and broken->destroyed
		self.lemit=[0,0,0] #Light emmision and color
		self.name="tile"

class GENERATOR():
	big_feature=perlin.PerlinNoise((1,1),perlin.ease_interpolation)
	small_feature=perlin.PerlinNoise((1,1),perlin.ease_interpolation)
	climate=perlin.PerlinNoise((1,1),perlin.ease_interpolation)
	lake=perlin.PerlinNoise((1,1),perlin.ease_interpolation)
	def __init__(self,big,small,climate,lake):
		debugMessage("Initializing generator...")
		self.big_feature   =perlin.PerlinNoise((big,big),perlin.ease_interpolation)
		self.small_feature =perlin.PerlinNoise((small,small),perlin.ease_interpolation)
		self.climate       =perlin.PerlinNoise((climate,climate),perlin.ease_interpolation)
		self.lake          =perlin.PerlinNoise((lake,lake),perlin.ease_interpolation)
		debugMessage("Generator initialized!")

class TILESET():
	tileset=[]
	tileDefinition=[]
	def __init__(self):
		debugMessage("Creating tileset...")
		self.tileDefinition+=[TILE()]
		for i in range(0,8):
			self.tileDefinition[0].images[i]=Rect(0,0,32,32)
		self.tileset=tileset=load_image("dngn.png")
		self.tileDefinition+=[TILE()]
		self.tileDefinition[1].strength=[]
		for i in range(1,8):
			self.tileDefinition[1].images[i-1]=Rect(i*32,0,32,32)
		self.tileDefinition+=[TILE()]
		self.tileDefinition[2].strength=[]
		for i in range(1,8):
			self.tileDefinition[2].images[i-1]=Rect(i*32+256,0,32,32)
		debugMessage("Tileset created!")
	def fromFile(self,filename):
		f=open(filename,"r")


class LOCALMAP():
	mapChunk=[[]]
	tileVariation=[[]]
	cachedimage="NULL"
	def generate(self,generator,positionX,positionY):
		debugMessage("Generating chunk...")
		for x in range(0,32):
			self.mapChunk+=[[]]
			self.tileVariation+=[[]]
			for y in range(0,32):
				nx = (x+positionX*32) / float(8)
				ny = (y+positionY*32) / float(8)
				if(  (generator.small_feature.value_at((nx,ny))*30) < 0  ):
					self.mapChunk[x]+=[0]
				else:
					self.mapChunk[x]+=[1]
				self.tileVariation[x]+=[random.randint(0,4)]
		debugMessage("Chunk generated("+str(positionX)+","+str(positionY)+")")
	def __init__(self,generator,positionX,positionY):
		self.mapChunk=[[]]
		self.tileVariation=[[]]
		self.generate(generator,positionX,positionY)
	def requestChunk(self,tileset):
		if self.cachedimage == "NULL":
			self.cachedimage=pygame.Surface((1024,1024))
			for x in range(0,32):
				for y in range(0,32):
					pos=(x*32,y*32)
					clip=tileset.tileDefinition[self.mapChunk[x][y]].images[self.tileVariation[x][y]]
					self.cachedimage.blit(tileset.tileset,pos,clip)
			debugMessage("Drawn a new chunk!")
		return self.cachedimage

class GLOBALMAP():       
	def __init__(self,big,small,climate,lake):
		debugMessage("Initializing world map...")
		self.chunkCollection={}
		self.generator=GENERATOR(big,small,climate,lake)
		debugMessage("World map initialized")

	def requestChunk(self, x, y):
		if not self.chunkCollection.has_key((x,y)):
			self.chunkCollection[(x,y)]=LOCALMAP(self.generator,x,y)
		return self.chunkCollection[(x,y)]
        
	def drawMap(self, screen, tileset, xx, yy):
                screen.fill((0,0,0))
		for x in range(-1,2):
			for y in range(-1,2):
                                chunk_x = (xx // 32) + x
                                chunk_y = (yy // 32) + y
                                
				chunk = self.requestChunk(chunk_x, chunk_y)
                                
                                pos = (32 * (32 * chunk_x - xx),
                                       32 * (32 * chunk_y - yy))
                                
                                if x == 0 and y == 0:
                                        print "blit: ", (xx, yy), (chunk_x, chunk_y), pos
                                        
				screen.blit(chunk.requestChunk(tileset), pos)

class GAME():
	camPositionX=0
	camPositionY=0
	camMovementX=0
	camMovementY=0
	run=0
	def __init__(self):
		debugMessage("Starting the game")
		pygame.init()
		pygame.display.set_caption('My game')
		pygame.mouse.set_visible(0)
		self.run=1
		debugMessage("Game started")

	screen = pygame.display.set_mode((640, 480))
	clock = pygame.time.Clock()
	tileset=TILESET()
	gamemap=GLOBALMAP(32,8,64,16)

	def main(self):
		debugMessage("Running main loop...")
		while(self.run):
			self.clock.tick(1000)
			self.camPositionX+=self.camMovementX
			self.camPositionY+=self.camMovementY
			self.checkEvents()
			self.gamemap.drawMap(self.screen,self.tileset,self.camPositionX,self.camPositionY)
			pygame.display.flip()
                        pygame.time.wait(10)
		debugMessage("Main loop off.")


	def checkEvents(self):
		for event in pygame.event.get():
			if event.type == QUIT:
				return
			elif event.type == KEYDOWN:
				if event.key == K_ESCAPE:
					self.run=0
					debugMessage("Disabling main loop...")
				elif event.key == K_RETURN:
					self.gamemap=GLOBALMAP(32,8,64,16)
				elif event.key == K_KP1:
					self.camMovementX=-1
					self.camMovementY=1
				elif event.key == K_KP2:
					self.camMovementY=1
				elif event.key == K_KP3:
					self.camMovementY=1
					self.camMovementX=1
				elif event.key == K_KP4:
					self.camMovementX=-1
				elif event.key == K_KP6:
					self.camMovementX=1
				elif event.key == K_KP7:
					self.camMovementX=-1
					self.camMovementY=-1
				elif event.key == K_KP8:
					self.camMovementY=-1
				elif event.key == K_KP9:
					self.camMovementY=-1
					self.camMovementX=1
			elif event.type == KEYUP:
				if event.key == K_KP1:
					self.camMovementX=0
					self.camMovementY=0
				elif event.key == K_KP2:
					self.camMovementY=0
				elif event.key == K_KP3:
					self.camMovementY=0
					self.camMovementX=0
				elif event.key == K_KP4:
					self.camMovementX=0
				elif event.key == K_KP6:
					self.camMovementX=0
				elif event.key == K_KP7:
					self.camMovementX=0
					self.camMovementY=0
				elif event.key == K_KP8:
					self.camMovementY=0
				elif event.key == K_KP9:
					self.camMovementY=0
					self.camMovementX=0
			elif event.type == MOUSEBUTTONDOWN:
				continue
			elif event.type is MOUSEBUTTONUP:
				continue
if __name__ == '__main__':
	game=GAME()
	game.main()
	debugMessage("Game ended")

