#!/usr/bin/env python

# level designer gui - this is used to design level graphics
# very rough and ready - main purpose is to allow quick game
# design. inputting levels by hand array is very tedious

import pygame
import os.path
import sys
import cPickle
import math

import utility

# draw the level actually
def draw_level (screen, leveldata, tileset):
		i = 0
		for row in leveldata:
			j = 0
			for tilerow, tilecol, is_solid in row:
				tilex = tilecol * 48
				tiley = tilerow * 48
				screen.blit (tileset, (j*48, i*48), pygame.Rect (tilex, tiley, 48, 48))
				if is_solid == 1:
					utility.put_text (screen, j*48+2, i*48+2, 10, (255,255,0), "w")
				j += 1
			i += 1

def display_menu (screen, tileset, tilerow, tilecol):
	utility.put_text (screen, 490, 10, 10, (255,255,0), "p to pick tile")
	utility.put_text (screen, 490, 50, 10, (255,255,0), "w to wall (solid)")
	utility.put_text (screen, 490, 90, 10, (255,255,0), "<Space> or  <Enter>")
	utility.put_text (screen, 490, 110, 10, (255,255,0), "to place")
	utility.put_text (screen, 490, 150, 10,(255,255,0), "Arrows to move around")
	utility.put_text (screen, 490, 190, 10, (255,255,0), "s to Save level")
	utility.put_text (screen, 490, 230, 10, (255,255,0), "q to Quit editor")

	# currently selected tile
	utility.put_text (screen, 490, 270, 10, (255,255,255), "Tile selected")
	screen.blit (tileset, (490, 290), (tilecol*48, tilerow*48, 48, 48))

# draw the tile cursor
def draw_cursor (screen, currow, curcol):
	pygame.draw.rect (screen, (255,255,255), (curcol*48, currow*48, 48, 48), 1)

# make wall
def make_wall (leveldata, row, col):
	# get the actual data in that place
	leveldata[row][col][2] = not leveldata[row][col][2]

# place a tile at current spot
def put_tile (leveldata, row, col, tilerow, tilecol):
	leveldata[row][col][0] = tilerow
	leveldata[row][col][1] = tilecol

# picking a tile from the tileset
def pick_tile (screen, tileset, selrow, selcol):

	# total number of rows and columns
	totalrows = tileset.get_height () / 48
	totalcols = tileset.get_width () / 48

	# implement scrolling within the tileset image in a 480x480 viewport

	# set the current page
	curpage_cols = selrow / 10
	curpage_rows = selcol / 10

	# cursor row and column
	cursor_row = selrow % 10
	cursor_col = selcol % 10

	# the code for scrolling through the tileset is slightly complicated here are the steps
	# logic goes like this
	# e.g. horizontal movement
	# left arrow key movement:
	# 1. reduce the absolute column by 1
	# 2. if absolute column < 0 then set absolute column to last column as total columns - 1
	# 3. calculate the current page based on absolute column as absolute column  / 10
	#    10 being the number of tile columns per page
	# 4. calculate the relative column on screen as (abolute column modulo 10) giving a
	#    division remainder between 0 and 9.

	# same logic is used for all other movements

	while 1:
		screen.fill (pygame.Color (0, 0, 0))
		screen.blit (tileset, (0, 0), (curpage_cols * 480, curpage_rows * 480, 480, 480))
		draw_cursor (screen, cursor_row, cursor_col)
		utility.put_text (screen, 490, 10,10, (255, 255, 0), "<Space> or <Enter>")
		utility.put_text (screen, 490, 30,10, (255, 255, 0), "to select tile")
		utility.put_text (screen, 490, 70,10, (255, 255, 0), "<Escape> to return")
		utility.put_text (screen, 10, 490,10, (255, 255, 0), "Selected: %d row, %d col" % (selrow, selcol))
		pygame.display.update ()
		for event in pygame.event.get ():
			if event.type == pygame.KEYDOWN:
				if event.key == pygame.K_ESCAPE:
					return None
				elif event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
					return selrow, selcol
				elif event.key == pygame.K_UP:
					# reduce the selected row by 1
					selrow -= 1
					if selrow < 0:
						selrow = totalrows - 1

					# calculate the current page
					curpage_rows = selrow / 10

					# calculate the current cursor row
					cursor_row = selrow % 10

				elif event.key == pygame.K_DOWN:
					# increase the selected row by 1
					selrow += 1
					if selrow >= totalrows:
						selrow = 0

					# calculate the current row page
					curpage_rows = selrow / 10

					# calculate the cursor row
					cursor_row = selrow % 10
				elif event.key == pygame.K_LEFT:
					# decrease the selected col by 1
					selcol -= 1
					if selcol < 0:
						selcol = totalcols - 1

					# calculate the current column page
					curpage_cols = selcol / 10

					# calculate the cursor column
					cursor_col = selcol % 10
				elif event.key == pygame.K_RIGHT:
					# increase the selected column by 1
					selcol += 1
					if selcol >= totalcols:
						selcol = 0

					# calculate the current column page
					curpage_cols = selcol / 10

					# calculate the cursor column
					cursor_col = selcol % 10

# the actual level editor
def level_editor (fname):
	# load level data
	leveldata = cPickle.load (file (fname))

	pygame.init ()
	# load the tileset
	tileset = pygame.image.load (os.path.join ("background", "tileset.png"))
	screen = pygame.display.set_mode ((720, 512))
	pygame.display.set_caption ("Level editor: %s" % fname)
	currow, curcol = 0, 0
	tilerow, tilecol = 0, 0

	while 1:
		screen.fill (pygame.Color (0, 0, 0))
		display_menu (screen, tileset, tilerow, tilecol)
		draw_level (screen, leveldata, tileset)
		draw_cursor (screen, currow, curcol)
		pygame.display.update ()
		for event in pygame.event.get ():
			if event.type == pygame.KEYDOWN:
				if event.key == ord ("q"):
					pygame.quit ()
					return
				elif event.key == ord ("s"):
					cPickle.dump (leveldata, file (fname, "w"))
					print ("Level saved")
				elif event.key == pygame.K_DOWN:
					currow += 1
					if currow > 9:
						currow = 0
				elif event.key == pygame.K_UP:
					currow -= 1
					if currow < 0:
						currow = 9
				elif event.key == pygame.K_LEFT:
					curcol -= 1
					if curcol < 0:
						curcol = 9
				elif event.key == pygame.K_RIGHT:
					curcol += 1
					if curcol > 9:
						curcol = 0
				elif event.key == pygame.K_SPACE or event.key == pygame.K_RETURN:
					put_tile (leveldata, currow, curcol, tilerow, tilecol)
				elif event.key == ord ("p"):
					tile = pick_tile (screen, tileset, tilerow, tilecol)
					if tile is not None:
						tilerow = tile[0]
						tilecol = tile[1]
				elif event.key == ord ("w"):
					make_wall (leveldata, currow, curcol)

def new_level ():
	print
	fname = raw_input ("New level file path: ")
	# prepare level with blank tiles
	leveldata = [
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]],
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
]
	# save the level first
	cPickle.dump (leveldata, file (fname, "w"))

	# now edit it
	level_editor (fname)

def load_level ():
	fname = raw_input ("Level file to load: ")
	level_editor (fname)

def main ():
	while 1:
		print
		print ("Level Editor for the Adventures of Butaba")
		print
		print ("1. Start a new level")
		print ("2. Load existing level")
		print ("3. Quit")

		ch = raw_input ("Your choice: ")
		if ch == "1":
			new_level ()
		elif ch == "2":
			load_level ()
		elif ch == "3":
			sys.exit (0)
		else:
			print ("Wrong choice. Must be 1, 2, or 3")


if __name__=="__main__":
	main ()
