﻿#import webbrowser
from bottle import Bottle, run, error, url, Jinja2Template, redirect, static_file, request
from bottle import jinja2_template as template #using jinja2 as template solution
#import circus #the game / simulation guts, what gets passed to templates
from circus import CircusAPI, NewGame
import sys

game_api = CircusAPI()
new_game = NewGame()

app = Bottle()

flash_message = ['']

def set_flash_message(new_flash_message):
	'''
	Sets the flash message. A flash message is a message that sits in a queue (a standard Python list) and is returned / deleted when 'flashed'.
	
	:param new_flash_message: A string representing the intended flash message.
	:type new_flash_message: String
	:returns: None
	
	'''
	flash_message.append(new_flash_message)
		
def get_flash_message():
	'''
	Retrieves the current flash message and deletes it from the top of the queue.
	
	:parameter: None
	:returns: String
	
	'''
	return flash_message.pop()

Jinja2Template.defaults = {'url': app.get_url,
							'player_info': game_api.player_info,
							'flash_message': get_flash_message()}

@app.route('/static-content/<filepath:path>')
def get_static_content(filepath):
	'''
	A housekeeping route for the purpose of telling the server where to serve static content - images, Javascript, CSS - from.
	
	:parameter filepath: Relative filepath to the static content.
	:type filepath: String
	:returns: URL to the content.
	
	:example URL: /css/main.css
	:method: GET
	
	'''
	return static_file(filepath, root = 'static-content')

@app.route('/template-test')
def template_test():
	return '<h1>hello</h1>'
	#return template('base.html', game = game_api)
	
@app.route('/redirect-test')
def redirect_test():
	redirect('/')

@app.route('/template-test/<id:int>')
def template_test_passthrough(id):
	return template('temptest.html', game = game_api, id_no = id)

@app.route('/', name = "splash")
def index():
	return template('splash.html')
	
#Top-level game menu routes

@app.route('/new_game', name = "new_game")
def new_game_screen():
	return template('new_game_info.html')
	
@app.route('/new_game/process', name = "start_new_game", method = 'POST')
def start_new_game():
	'''
	Takes the info from new_game_screen() and uses it to, well, start a new game.
	
	:method: POST
	:parameter school_name: The name of the School.
	:type school_name: String
	:parameter school_motto: The motto of the School.
	:type school_motto: String
	:returns: Redirect ('/game')
	'''
	school_name = request.forms.get('school_name')
	school_motto = request.forms.get('school_motto')
	new_game.new_game(school_name, school_motto)
	redirect('/game')
	
@app.route('/options', name = 'options_summary')
def options_menu():
	return template('options_summary.html')
	
@app.route('/load-game')
def load_game_menu():
	#scan /save directory for folders, load names, allow option to select particular folder then load and redirect to /game
	return "LOAD GAME"
	
@app.route('/exit', name = "exit_screen")
def quit_app():
	#confirmation screen before exiting
	return template('confirm_exit_screen')
	
@app.route('/confirmed-exit', name = "confirmed-exit")
def exit_circus():
	#http://stackoverflow.com/questions/11282218/bottle-web-framework-how-to-stop
	sys.stderr.close()
	
#In-game routes

@app.route('/game', name = 'main_screen_summary')
def game_summary():
	'''
	Loads the main game summary screen. Calls the CircusAPI.get_last_round_matches() and CircusAPI.get_player_school_info() functions.
	
	:example URL: /game
	:method: GET
	'''
	
	last_round_matches = game_api.get_last_round_matches()
	school_info = game_api.get_player_school_info()
	return template('player_summary.html', last_matches = last_round_matches, school = school_info)
	
@app.route('/game/markets', name = 'list_of_markets')
def markets_summary():
	'''
	Generates a page that lists all available Markets.
	
	:example URL: /game/markets
	:method: GET
	'''
	market_list = game_api.get_markets()
	return template('all_markets.html', markets = market_list)
	
@app.route('/game/markets/<id:int>', name = 'specific_market')
def specific_market_summary(id):
	'''
	Displays the contents of a particular Market, allowing the player to purchase those items (Fighters or Items)
	
	:parameter id: The number representing a specific Market.
	:type id: int
	
	:example URL: /game/markets/2
	:method: GET
	
	'''
	specific_market = game_api.get_specific_market_contents(id)
	if specific_market.type == 'fighters':
		market_contents = game_api.get_fighter_market(id)
		return template('specific_fighter_market.html', market = specific_market, market_guts = market_contents)
	elif specific_market.type == 'items':
		market_armour = game_api.get_armour_market(id)
		market_weapon = game_api.get_weapon_market(id)
		return template('specific_item_market.html', market = specific_market, list_weapon = market_weapon, list_armour = market_armour)
		
@app.route('/game/item/<type>/<id:int>', name = 'view_item')
def view_item(type, id):
	'''
	View specific details about a paritcular item.
	
	:parameter type: The type of item. Can be Weapon or Armour.
	:type type: string
	
	:parameter id: The unique number representing a specific item.
	:type id: int
	
	:example URL: /game/item/weapon/32
	:method: GET
	
	'''
	valid_types = ['weapon', 'armour']
	if type not in valid_types:
		return "NOPE"
	elif type == "weapon":
		weapon_info = game_api.get_specific_item('weapon', id)
		return template('view_item', item_type = type, info = weapon_info)
	elif type == "armour":
		armour_info = game_api.get_specific_item('armour', id)
		return template('view_item', item_type = type, info = armour_info)

@app.route('/game/markets/buy_item/<type>/<id:int>', name = 'buy_item')
def buy_player_item(type, id):
	'''
	Allows a player to purchase an item (providing they have the funds) and add it to their Armoury. Will set an appropriate flash message and redirect player depending on success or failure.
	
	:parameter type: The type of item. Can be Weapon or Armour.
	:type type: string
	
	:parameter id: The unique number representing a specific item.
	:type id: int
	
	:example URL: /game/makets/buy_item/armour/12
	:method: GET
	
	'''
	if game_api.buy_item_for_player(type, id):
		set_flash_message('Purchase successful!')
		redirect('/game/markets')
	else:
		set_flash_message('Unsuccessful purchase.')
		redirect('/game/markets')
	
@app.route('/game/markets/buy_fighter/<id:int>', name = 'buy_fighter')
def buy_fighter(id):
	'''
	Buys a Fighter for a player, presuming they have the funds.
	
	
	'''
	if game_api.buy_fighter_for_player(id):
		return template('successful_fighter_purchase.html')
	else:
		redirect('/game/markets')
		
@app.route('/game/stable/armoury', name = 'player_armoury')
def armoury_summary():
	'''
	Lists all of the player's owned armour and weapons.
	'''
	player_weapons = game_api.get_player_owned_weapons()
	player_armours = game_api.get_player_owned_armour()
	return template('all_player_armoury.html', list_weapon = player_weapons, list_armour = player_armours)
	
@app.route('/game/stable/armoury/<type>/<id:int>', name = 'specific_owned_item')
def armoury_item_summary(type, id):
	'''
	This is where a specific item's details is viewed from. From this page you can also equip a fighter with it.
	
	:parameter type: The particular kind of Item. Can be Weapon or Armour.
	:type type: string
	
	:parameter id: The unique number representing a specific Item.
	:type id: int
	
	:example URL: /game/stable/armour/weapon/3
	:method: GET
	
	'''
	valid_types = ['weapon', 'armour']
	player_stable = game_api.get_owned_fighters()
	if type not in valid_types:
		return "NOPE"
	elif type == "weapon":
		weapon_info = game_api.get_specific_item('weapon', id)
		return template('view_player_armoury_item', item_type = type, info = weapon_info, fighter_list = player_stable)
	elif type == "armour":
		armour_info = game_api.get_specific_item('armour', id)
		return template('view_player_armoury_item', item_type = type, info = armour_info, fighter_list = player_stable)
	
@app.route('/game/stable/equip/<fighter:int>/<type>/<id:int>/<location>', name = 'equip_fighter')
def equip_item_to_fighter(fighter, type, id, location):
	'''
	Equips a specific item to a specific player.
	
	:parameter fighter: The number representing a specific Fighter.
	:type fighter: int
	
	:parameter type: The kind of item. Can be Weapon or Armour
	:type type: string
	
	:parameter id: The number representing a specific Item.
	:type id: int
	
	:parameter location: The location to which the item is being equipped.
	:type location: string
	
	:example URL: /game/stable/equip/2/armour/head
	:method: GET
	
	'''
	if game_api.equip_fighter_with_item(fighter, type, id, location):
		#equip was successful
		redirect('/game/stable')
	else:
		#equip was unsuccessful
		return "OH NO"
		
@app.route('/game/stable/unequip/<type>/<id:int>', name = 'unequip_item')
def unequip_item(type, id):
	'''
	Unequips an item.
	
	:parameter type: The type of Item. Can be Weapon or Armour.
	:type type: string
	
	:parameter id: The unique number representing a specific Item.
	:type id: int
	
	:example URL: /game/stable/unequip/armour/3
	:method: GET
	
	'''
	if type == 'weapon':
		if game_api.unequip_weapon_item(id):
			redirect('/game/stable/armoury')
	elif type == 'armour':
		if game_api.unequip_armour_item(id):
			redirect('/game/stable/armoury')
	
@app.route('/game/stable', name = 'player_stable')
def stable_summary():
	'''
	Allows a player to view their purchased Fighters and various sub-menus.
	
	:example URL: /game/stable
	'''
	player_stable = game_api.get_owned_fighters()
	return template('fighter_stable.html', stable = player_stable)
	
@app.route('/game/stable/<id:int>', name = 'specific_fighter')
def specific_stable_member_summary(id):
	'''
	Allows the player to view a particular Fighter's stats and details.
	
	:parameter id: The unique number representing a specific Fighter.
	:type id: int
	
	:example URL: /game/stable/3
	:method: GET
	
	'''
	stable_entry = game_api.get_specific_fighter(id)
	#stable_matches = game_api.get_specific_fighter_matches(id)
	return template('specific_fighter.html', fighter = stable_entry)
	#return template('specific_fighter.html', fighter = stable_entry, matches = stable_matches)
	
@app.route('/game/training', name = 'fighter_training')
def training_summary():
	'''
	Allows a player to view their training schedule.
	
	:example URL: /game/training
	:method: GET
	
	'''
	return template('training.html')

@app.route('/game/training/all_training', name = 'process_all_training', method = 'POST')
def process_all_training():
	'''
	Trigger for setting a universal training schedule.
	
	:example URL: /game/training/all_training
	:method: POST
	
	'''
	#the POST route that triggers adding training to all fighter schedules
	to_train = request.forms.get('focus') #from the form
	#print to_train
	game_api.set_universal_training_schedule(to_train)
	redirect('/game/training')
	
@app.route('/game/training/<id:int>')
def specific_training(id):
	#this is where you can tweak an individual fighter's training schedule
	return "YEAH THEY'RE ALRIGHT"
	
@app.route('/game/events', name = 'all_events_summary')
def view_events():
	'''
	Allows a player to view available events.
	
	:example URL: /game/events
	:method: GET
	'''
	available_events = game_api.get_available_events()
	return template('all_open_events.html', all_events = available_events)
	
@app.route('/game/events/<event:int>', name = 'specific_event_summary')
def view_specific_event(event):
	'''Lists all the matches in an event and allows you to enter Fighters in them.
	
	:parameter event: The unique number for a specific event.
	:type event: int
	
	:example URL: /game/events/3
	:method: GET
	
	'''
	specific_event_info = game_api.get_specific_event(event)
	event_match_info = game_api.get_specific_event_fights(event)
	unbooked_fighters = game_api.get_owned_unbooked_fighters()
	return template('specific_event_and_entry.html', fight_event = specific_event_info, matches = event_match_info, stable = unbooked_fighters)
	
@app.route('/game/events/book', method = 'POST', name = 'book_fighter')
def enter_specific_fighter():
	'''
	Enters a particular fighter in a particular match.
	
	:example URL: /game/events/book
	:method: POST
	
	:form data: fighter_id (int), match_id (int)
	
	'''
	fighter_id = request.forms.get('fighter_id')
	match_id = request.forms.get('match_id')
	if game_api.book_fighter(fighter_id, match_id):
		redirect('/game/events')
	else:
		print "SOMETHING WENT WRONG?!"
		
@app.route('/game/events/all_previous', name = 'previous_rounds')
def view_previous_rounds():
	'''
	Allows a player to view all the previous rounds.
	
	:example URL: /game/events/all_previous
	:method: GET:
	'''
	previous = game_api.get_all_previous_matches()
	return template('view_previous_events', matches = previous)
	
@app.route('/game/events/all_previous/<id:int:>', name = 'previous_detail')
def view_previous_matches(id):
	'''
	Allows a player to view the matches of a previous round.
	
	:parameter id: I can't remember???
	:type id: int
	
	:example URL: /game/events/all_previous/3
	:method: GET
	'''
	previous = game_api.get_previous_match_rounds(id)
	return template('view_previous_events_rounds.html', rounds = previous)

'''	
@app.route('/game/events/<match:int>', name = 'specific_match')
def view_specific_math(match):
	#where you see specific matches
	return template('specific_event_and_entry.html')'''
	
@app.route('/end-turn', name = 'end_turn')
def end_game_turn():
	game_api.new_turn_process()
	redirect('/game')

#Housekeeping routes
	
@app.error(404)
def error404(code):
	return '<p>Sorry. Nothing here. 404.</p>'

if __name__ == "__main__":	
	run (app, host = 'localhost', port = 8080, debug = True, reloader = True)
	#webbrowser.open_new_tab('http://localhost')