#!/usr/bin/python
# File: py_eye_gui.py
# Author: Yosi Izaq
# Description: GUI for py_eye utility

"""
GPL licensing

(C) Copyright, 2007 Yosi Izaq.

This file, py_eye_gui.py, is part of PyEye programm.

PyEye is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

PyEye is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with PyEye.  If not, see <http://www.gnu.org/licenses/>.
"""

"""
ToDo:
	1. Add game [done]
	2. remove game [done]
	3. edit game [done]
	4. query all games [cancel]
	5. Propogate the results of server response to GUI. 
		5.1 Handle connection refused.
		5.2 Add flags for all nations [done]
	6. Handle games w/o age (perpetuality] [done]
	7. Add tooltips to nation flag giving status in words [done]
	8. D/L larger icons for nation status [done]
	9. Verify working for windows and Linux
	10. Create an install script and an exe for windows [done]
	http://docs.python.org/dist/node13.html
	http://python.active-venture.com/dist/simple-example.html
	http://docs.python.org/dist/setup-script.html
	11. Bug, change color doesn't work after query [fixed]
	12. Fix the bg color to apply to query frame [fixed]
	13. Fix spacing of statys icons [fixed]
	14. Add horiontal and vertical scroll bars. [done]
	15. Add tooltips for icons [done]
	16. When game name changes or added or removed update the query menu. [done]
	17. Display time to next host.[done]
	18. Make game configuration name not dependent on actual game name.[done]
	19. Cleanup, change demo names, remove comments etc.
	20. save "auto save turn" setting to configuration file like games path, flags etc.
"""

from Tkinter import *
from SimpleDialog import SimpleDialog #Simple dialog for help menu
from tkColorChooser import askcolor   #color dialog for background
from tkFileDialog   import askopenfilename        # File open standard dialog
from tkSimpleDialog import askstring		  # string data entry, use for game flags
from tkFileDialog import askdirectory	#Choose directory dialog for choosing save turn directory

#Since PIL install on cygwin fails I prefer not use it to keep the utility truly cross platform
#from PIL import Image, ImageTk #for working with tga images
import logging
import os
#import thread
import threading

##user imports
import py_eye #dominions III client
from py_eye import *

import Tooltip#tooltip implemenation for tkinter
from Tooltip import *
import FrameScrollBar#For pattern that allows putting frame in canvas and attaching a scrollbar to it.
from FrameScrollBar import *

#Logging configuration:
FORMAT = "%(asctime)-15s %(levelname)s %(message)s"

#Uncomment or comment according to required debugging level
#For normal prints
logging.basicConfig(format=FORMAT)
#For debug info
#logging.basicConfig(level=logging.DEBUG, format=FORMAT, filename='./py_eye_gui.log', filemode='w')

pyEyeGUILogger = logging.getLogger("PyEyeGUILogger")

## define a Handler which writes INFO messages or higher to the sys.stderr
#console = logging.StreamHandler()
#console.setLevel(logging.NOTSET)
## set a format which is simpler for console use
#formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
## tell the handler to use this format
#console.setFormatter(formatter)
## add the handler to the root pyEyeGUILogger
#logging.getLogger('').addHandler(console)

#End of logging configuration

class DomIIIRunner(threading.Thread):
	"""
Class for spawning a thread per running of dominions III
Currently there is some issue that calls to os.system cause the thread to die 
unexpectedly w/o throwing an exception.
	"""

	m_domIII_cmd = None

	def __init__(self, domIII_cmd):
	    threading.Thread.__init__(self)        
	    self.m_domIII_cmd = domIII_cmd

	def run(self):
		#pyEyeGUILogger.debug("Spawning thread for running dominions III client with command %s"%(m_domIII_cmd))
		print "Running thread with command %s"%self.m_domIII_cmd
		if self.m_domIII_cmd != None:
			print "Running Dominions III"
			try:
				os.system("ls")
				print "Running Dominions III"
				os.system(self.m_domIII_cmd)
			except:
				print "exception caught"
		else:
			print "Received invalid command. Can't execute dom III!"
		print "Finished running thread"
			#pyEyeGUILogger.warning("Received invalid command. Can't execute dom III!")
#End of class DomIIIRunner

# Utility classes for entry widget validation:
class ValidatingEntry(Entry):
    # base class for validating entry widgets

    def __init__(self, master, value="", **kw):
        apply(Entry.__init__, (self, master), kw)
        self.__value = value
        self.__variable = StringVar()
        self.__variable.set(value)
        self.__variable.trace("w", self.__callback)
        self.config(textvariable=self.__variable)

    def __callback(self, *dummy):
        value = self.__variable.get()
        newvalue = self.validate(value)
        if newvalue is None:
            self.__variable.set(self.__value)
        elif newvalue != value:
            self.__value = newvalue
            self.__variable.set(self.newvalue)
        else:
            self.__value = value

    def validate(self, value):
        # override: return value, new value, or None if invalid
        return value

class IntegerEntry(ValidatingEntry):

    def validate(self, value):
        try:
            if value:
                v = int(value)
            return value
        except ValueError:
            return None

class FloatEntry(ValidatingEntry):

    def validate(self, value):
        try:
            if value:
                v = float(value)
            return value
        except ValueError:
            return None

class MaxLengthEntry(ValidatingEntry):

    def __init__(self, master, value="", maxlength=None, **kw):
        self.maxlength = maxlength
        apply(ValidatingEntry.__init__, (self, master), kw)

    def validate(self, value):
        if self.maxlength is None or len(value) <= self.maxlength:
            return value
        return None # new value too long

class AboutDialog:
    def __init__(self, parent, version):

        top = self.top = Toplevel(parent)

        #Label(top, text="PyEye GUI.       \nCreated by:\nYosi Izaq (aka Wraithlord).").pack()
	Label(top, text="PyEye GUI ver %s.\nCreated by Yosi Izaq (aka Wraithlord).\n\nThanks:\n\tZepath, for the beautiful nation icons.\n\tIch, for fixing the 3.14 related status error.\n\tJurri, who has helped by giving comments and the program's icon and for being my eternal foe\n\tShrapnel games for hosting dominions forums\n\tAnd last but far from least, IW for giving us this dominions!\n\n I hope you may find this tool useful, for my purpose in creating it was to give back to the great players community of Dominions III\n\n\n"%(version)).pack()


	photo = PhotoImage(file=r"./icons/WL.gif")
	w = Label(top, image=photo)
	w.photo = photo
	w.pack()

#        self.e = Entry(top)
#        self.e.pack(padx=5)

        b = Button(top, text="OK", command=self.ok)
        b.pack(pady=5)

    def ok(self):

        #print "value is", self.e.get()
        self.top.destroy()

class BaseGameFormCreator:
	"""
	Base class for add/remove/edit game forms
	"""

	game_name = None

class AddOrEditGameFormCreator:
	"""
	Base class for add/edit game forms
	"""
	game_name	= ""
	game_host	= ""
	game_port	= ""
	#game_age	= ""
	#game_nation	= ""
	m_cfg		= None
	m_nations_listbox  = None
	m_nations_list = []

	win = 0
	entry1 = 0
	entry2 = 0
	entry3 = 0
	var4 = 0
	

	def __init__(self, cfg):
		self.m_cfg = cfg


	def AddNationsListToForm(self, nation = ""):
		#drop down list for selecting nation.
		pyEyeLogger.debug("Starting method AddOrEditGameFormCreator::AddNationsListToForm() with parmater, nation=%s "%(nation))
		nations_frame = Frame(self.win)
		nations_scrollbar = Scrollbar(nations_frame, orient=VERTICAL)
		self.m_nations_listbox = Listbox(nations_frame, bd=0, yscrollcommand=nations_scrollbar.set)
		nations_scrollbar.config(command=self.m_nations_listbox.yview)
		nations_scrollbar.pack(side=RIGHT, fill=Y)
		self.m_nations_listbox.pack(side=LEFT, fill=BOTH, expand=1)

		nations_dict_list = [self.m_cfg.m_early_nations_dict, self.m_cfg.m_mid_nations_dict, self.m_cfg.m_late_nations_dict]
		default_nation_id = None
		for current_dict in nations_dict_list:
			for nation_id, nation_cfg in current_dict.iteritems(): 
				pyEyeGUILogger.debug("Adding nation %s to nations drop down list"%(nation_cfg.m_name))
				self.m_nations_listbox.insert(END, nation_cfg.m_name)
				self.m_nations_list.append( nation_cfg.m_name)
				if (nation_cfg.m_name == nation):
					pyEyeLogger.debug("Matched default selection nation %s to id %s "%(nation, nation_id))
					default_nation_id = nation_id
		#nations_listbox.grid(row=5, rowspan=3, columnspan=5)
		#nations_scrollbar.grid(row=5, column=2)
		# attach listbox to scrollbar
		#nations_listbox.config(yscrollcommand=nations_scrollbar.set)
		#nations_scrollbar.config(command=nations_listbox.yview)
		if (default_nation_id != None):
			pyEyeLogger.debug("Setting default selection nation %s, id %s "%(nation, default_nation_id))
			#Set default selection if any
			self.m_nations_listbox.selection_set(default_nation_id)
		nations_frame.grid(row=5, column =1)


class RemoveGameFormCreator(BaseGameFormCreator):
	listbox = 0

	#game_name = ""
		# Add the simple dialog of choosing from list of choices made of config parsers sections 
		#listbox 
		

	def createForm(self, games, removeGameCallback):
		self.win = Toplevel( )
		Label(self.win,  text='Please choose which game to remove').grid(row=0)

		self.listbox = Listbox(self.win, selectmode=EXTENDED)
		for game in games:
			self.listbox.insert(END, game)

		self.listbox.grid(row=1)

		bOk = Button(self.win, text="OK", command = removeGameCallback)
		bOk.grid(row=2)

		pyEyeGUILogger.debug("Remove Game Form creation complete")

class EditGameSelectionFormCreator:
	listbox = 0

	game_name = ""

	def createForm(self, games, editGameCallback):
		self.win = Toplevel( )
		Label(self.win,  text='Please choose which game to edit').grid(row=0)

		self.listbox = Listbox(self.win, selectmode=SINGLE)
		for game in games:
			self.listbox.insert(END, game)

		self.listbox.grid(row=1)

		bOk = Button(self.win, text="OK", command = editGameCallback)
		bOk.grid(row=2)

		pyEyeGUILogger.debug("Select edit game form creation complete")

class EditGameFormCreator(AddOrEditGameFormCreator):

#	#ToDo, load initial value from configuration
#	game_name = ""
#	game_host = ""
#	#ToDo Validate valid port input
#	game_port = ""
#	#ToDo, make it selection
#	game_age = ""
#	win = 0
#	entry1 = 0
#	entry2 = 0
#	entry3 = 0
#	var4 = 0
	

	game_nation = ""

	def createForm(self, config, game, editGameCallback):
		self.win = Toplevel( )
		pyEyeGUILogger.debug("Game values: %s"%(config.readSection(game)))
		for option, value in config.readSection(game):
			if (option == 'host'):
				self.game_host = value
			if (option == 'age'):
				self.game_age = value
			if (option == 'port'):
				self.game_port = value
			if (option == 'nation'):
				self.game_nation = value

		#Label(win,  text='Please fill the new game form').pack(side=TOP )
		pyEyeGUILogger.debug("Adding Label")
		Label(self.win,  text='Please fill the edit game form').grid(row=0)
	
		#Entry (for game name)
		pyEyeGUILogger.debug("Adding Game entry")
		def get_game_name():
			self.game_name = self.entry1.get() 
			pyEyeGUILogger.debug("Game name input: %s"%(self.game_name)) 

		content1 = StringVar()
		self.entry1 = Entry(self.win,  textvariable=content1)
		text1 = content1.get()
		Label(self.win,  text='game name:').grid(row=1)
		content1.set(game)
		self.entry1.grid(row=1, column=1)
		
		#Entry (for game host)
		pyEyeGUILogger.debug("Adding Host entry")
		def get_game_host():
			self.game_host = self.entry2.get() 
			pyEyeGUILogger.debug("Game host input: %s"%(self.game_host)) 

		content2 = StringVar()
		self.entry2 = Entry(self.win,  textvariable=content2)
		text2 = content2.get()
		Label(self.win,  text='game host:').grid(row=2)
		content2.set(self.game_host)
		self.entry2.grid(row=2, column=1)
		
		#Entry (for game port)
		pyEyeGUILogger.debug("Adding game port entry")
		def get_game_port():
			self.game_port = self.entry3.get() 
			pyEyeGUILogger.debug("Game port input: %s"%(self.game_port))


		content3 = StringVar()
		self.entry3 = IntegerEntry(self.win , self.game_port)
		Label(self.win,  text='game port:').grid(row=3)
		self.entry3.grid(row=3, column=1)

# Age chioce
		MODES = [
			("Early", "early"),
			("Middle", "mid"),
			("Late", "late"),
			("All Ages", "all"),
		]

		self.var4 = StringVar()
		self.var4.set(self.game_age) # initialize

		col = 1
		for text, mode in MODES:
			button4 = Radiobutton(self.win, text=text,
					variable=self.var4, value=mode, 
				#	command=self.printChoice()
					)
			button4.grid(row=4, column=col)
			col = col +1

		self.AddNationsListToForm(self.game_nation)

		bOk = Button(self.win, text="OK", command = editGameCallback)
		bOk.grid(row=6, column=1)

		pyEyeGUILogger.debug("Edit Game Form creation complete")

class AddGameFormCreator(AddOrEditGameFormCreator):

#	game_name	= ""
#	game_host	= ""
#	game_port	= ""
#	#game_age	= ""
#	#game_nation	= ""
#	m_cfg		= None
#	m_nations_listbox  = None
#	m_nations_list = []
#
#	win = 0
#	entry1 = 0
#	entry2 = 0
#	entry3 = 0
#	var4 = 0
	
#	def __init__(self, cfg):
#		self.m_cfg = cfg


	def createForm(self, addGameCallback):
		self.win = Toplevel( )
		#Label(win,  text='Please fill the new game form').pack(side=TOP )
		pyEyeGUILogger.debug("Adding Label")
		Label(self.win,  text='Please fill the new game form').grid(row=0)
	
		#Entry (for game name)
		pyEyeGUILogger.debug("Adding Game entry")
		def get_game_name():
			self.game_name = self.entry1.get() 
			pyEyeGUILogger.debug("Game name input: %s"%(self.game_name)) 

		content1 = StringVar()
		self.entry1 = Entry(self.win,  textvariable=content1)
		text1 = content1.get()
		#Label(self.win,  text='game name:').pack(side=LEFT )
		Label(self.win,  text='game name:').grid(row=1)
		content1.set("<Game name>")
		#self.entry1.pack(side=RIGHT)
		self.entry1.grid(row=1, column=1)
		
		#bind to enter key
		#self.entry1.bind('<Return>', (lambda event: get_game_name()))


		#Entry (for game host)
		pyEyeGUILogger.debug("Adding Host entry")
		def get_game_host():
			self.game_host = self.entry2.get() 
			pyEyeGUILogger.debug("Game host input: %s"%(self.game_host)) 

		content2 = StringVar()
		self.entry2 = Entry(self.win,  textvariable=content2)
		text2 = content2.get()
		#Label(self.win,  text='game host:').pack(side=LEFT )
		Label(self.win,  text='game host:').grid(row=2)
		content2.set("<Game host>")
		self.entry2.grid(row=2, column=1)
		
		#Entry (for game port)
		pyEyeGUILogger.debug("Adding game port entry")
		def get_game_port():
			self.game_port = self.entry3.get() 
			pyEyeGUILogger.debug("Game port input: %s"%(self.game_port))


		content3 = StringVar()
		self.entry3 = IntegerEntry(self.win , "2345" )
		#Label(self.win,  text='game host:').pack(side=LEFT )
		Label(self.win,  text='game port:').grid(row=3)
		self.entry3.grid(row=3, column=1)

# Age chioce
		MODES = [
			("Early", "early"),
			("Middle", "mid"),
			("Late", "late"),
			("All Ages", "all"),
		]

		self.var4 = StringVar()
		self.var4.set("early") # initialize

		col = 0
		for text, mode in MODES:
			button4 = Radiobutton(self.win, text=text,
					variable=self.var4, value=mode, 
				#	command=self.printChoice()
					)
			button4.grid(row=4, column=col)
			col = col +1

		self.AddNationsListToForm()
#		#drop down list for selecting nation.
#		nations_frame = Frame(self.win)
#		nations_scrollbar = Scrollbar(nations_frame, orient=VERTICAL)
#		self.m_nations_listbox = Listbox(nations_frame, bd=0, yscrollcommand=nations_scrollbar.set)
#		nations_scrollbar.config(command=self.m_nations_listbox.yview)
#		nations_scrollbar.pack(side=RIGHT, fill=Y)
#		self.m_nations_listbox.pack(side=LEFT, fill=BOTH, expand=1)
#
#		nations_dict_list = [self.m_cfg.m_early_nations_dict, self.m_cfg.m_mid_nations_dict, self.m_cfg.m_late_nations_dict]
#		for current_dict in nations_dict_list:
#			for nation_id, nation_cfg in current_dict.iteritems(): 
#				pyEyeGUILogger.debug("Adding nation %s to nations drop down list"%(nation_cfg.m_name))
#				self.m_nations_listbox.insert(END, nation_cfg.m_name)
#				self.m_nations_list.append( nation_cfg.m_name)
#		#nations_listbox.grid(row=5, rowspan=3, columnspan=5)
#		#nations_scrollbar.grid(row=5, column=2)
#		# attach listbox to scrollbar
#		#nations_listbox.config(yscrollcommand=nations_scrollbar.set)
#		#nations_scrollbar.config(command=nations_listbox.yview)
#		nations_frame.grid(row=5, column =1)


		bOk = Button(self.win, text="OK", command = addGameCallback)
		bOk.grid(row=6, column =1)

		pyEyeGUILogger.debug("Adding Game Form creation complete")

#Main class for GUI
class pyEyeGui:
	m_version		= 1.32
	m_master  		= 0
	m_root_frame		= 0
	m_status_frame		= 0
	m_cfg			= pyEyeCfg()
	m_bg			= "gray"
	m_menubar		= None
	m_is_auto_save		= "off" #control whether or not turns will be saved automatically after played.


	def create_settings_menu(self, auto_save='off'):
		# Settings menu, mainly setup dom-III exe path for launching network games
		settingsmenu = Menu(self.m_menubar, tearoff=0)
		settingsmenu.add_command(label="Set game path", command=self.set_dom_path)
		settingsmenu.add_command(label="Set game flags", command=self.set_dom_flags)
		settingsmenu.add_separator()
		settingsmenu.add_command(label="Set turns backup path", command=self.set_backup_path)
		settingsmenu.add_separator()
		pyEyeGUILogger.debug("[py_eye_gui::create_settings_menu()] Setting auto save to: %s"%auto_save)
		settingsmenu.add_command(label="Auto save "+auto_save, 
				command=self.set_auto_save)
		#self.m_menubar.add_cascade(label="Settings", menu=settingsmenu)
		self.m_menubar.insert_cascade(6, label="Settings", menu=settingsmenu)


	def create_top_level_menus(self):
		"""
		Create the top level menus for the utility
		"""

		pyEyeGUILogger.debug("[py_eye_gui::create_top_level_menus()] started")
		#Top level menu
		# create a toplevel menu
		self.m_menubar = Menu(self.m_master)

		# create a pulldown menu, and add it to the menu bar
		filemenu = Menu(self.m_menubar, tearoff=0)
		filemenu.add_command(label="File", command=self.games)
		#filemenu.add_command(label="Save", command=self.hello)
		filemenu.add_separator()
		filemenu.add_command(label="Color", command=self.set_color)
		filemenu.add_separator()
		filemenu.add_command(label="Exit", command=self.m_master.quit)
		self.m_menubar.add_cascade(label="File", menu=filemenu)

		#Game status query submenu
		gamesmenu = Menu(self.m_menubar, tearoff=0)
		gamesmenu.add_command(label="Query all", command=self.query_all_games)
		gamesmenu.add_separator()
		for game in self.m_cfg.m_games.keys():
			gamesmenu.add_command(label=game, command= lambda p_game = game: self.query_game(p_game))
		self.m_menubar.add_cascade(label="Query", menu=gamesmenu)
	

		#Game launch submenu
		launchmenu = Menu(self.m_menubar, tearoff=0)
		for game in self.m_cfg.m_games.keys():
			launchmenu.add_command(label=game, command= lambda p_game = game: self.launch_game(p_game))
		self.m_menubar.add_cascade(label="Play turn", menu=launchmenu)
		

		#Save turns submenu
		savemenu = Menu(self.m_menubar, tearoff=0)
		for game in self.m_cfg.m_games.keys():
			savemenu.add_command(label=game, command= lambda p_game = game: self.save_turn(p_game))
		self.m_menubar.add_cascade(label="Save turn", menu=savemenu)
		
		# Game query configuration menu
		editmenu = Menu(self.m_menubar, tearoff=0)
		editmenu.add_separator()
		editmenu.add_command(label="Add Game", command=self.add_game)
		editmenu.add_command(label="Remove Game", command=self.remove_game)
		editmenu.add_command(label="Edit Game", command=self.edit_game)
		#editmenu.add_command(label="Copy", command=self.hello)
		#editmenu.add_command(label="Paste", command=self.hello)
		self.m_menubar.add_cascade(label="Games", menu=editmenu)

		#Settings menu
		self.create_settings_menu(self.m_is_auto_save)

		#Help menu
		helpmenu = Menu(self.m_menubar, tearoff=0)
		helpmenu.add_command(label="Usage", command=self.usage)
		helpmenu.add_separator()
		helpmenu.add_command(label="About", command=self.about)
		self.m_menubar.add_cascade(label="Help", menu=helpmenu)

	def __init__(self, master):
		pyEyeGUILogger.debug("[py_eye_gui::__init__()] started")
 
		self.m_master = master
		frame = Frame(master, width=900, height=600, bg=self.m_bg, bd=3, relief= GROOVE)
		#frame.pack_propagate(False) #make the frame fixed size
		frame.pack(side=TOP, expand=NO, fill=NONE)
		self.m_root_frame = frame

		#status_frame = Frame(frame)
		#w = Label(status_frame, text="Hello", font=("Helvetica", 16))
		#w.grid(row=0)
		##w.pack()
		#status_frame.pack()
		#frame = Frame(master)
		#frame.pack()

		#Set auto save value
		self.m_is_auto_save = self.m_cfg.m_settings['auto_save_turns']

		self.create_top_level_menus()

		# display the menu
		master.config(menu=self.m_menubar)


	def cb(self):
	        print "variable is", self.var.get()

	def printChoice(self):
	        print "choice is", self.var1.get()

	def set_color(self):
		pyEyeGUILogger.debug("Setting background color")
		(triple, self.m_bg) = askcolor()
		if self.m_bg:
			pyEyeGUILogger.debug("Setting background color to: %s"%(self.m_bg))
			self.m_root_frame.config(bg=self.m_bg)
			self.m_master.config(bg=self.m_bg)

	def say_hi(self):
		print "hi there, everyone!"

	def add_game(self):
		pyEyeGUILogger.debug("[py_eye_gui::add_game()] started")

		game_name	= None
		game_host 	= None
		game_port 	= None
		game_nation	= None

		#Callback for form
	#Callback of ok button
		gameForm = AddGameFormCreator(self.m_cfg)

		def okGameForm():
			game_name = gameForm.entry1.get() 
			pyEyeGUILogger.debug("Game name input: %s"%(game_name)) 
			game_host = gameForm.entry2.get() 
			pyEyeGUILogger.debug("Game host input: %s"%(game_host)) 
			game_port = gameForm.entry3.get() 
			pyEyeGUILogger.debug("Game port input: %s"%(game_port))
			game_age = gameForm.var4.get() 
			pyEyeGUILogger.debug("Game age input: %s"%(game_age))
			#Get selected nation
			game_nation = gameForm.m_nations_listbox.curselection()
			try:
    			    game_nation = map(int, game_nation)
    			except ValueError: pass

			pyEyeGUILogger.debug("Nation list len: %d, list of selected nations len: %d."%(len(gameForm.m_nations_list), len(game_nation)))
			if (len(game_nation) > 0):
				game_nation = gameForm.m_nations_list[game_nation.pop()]

			pyEyeGUILogger.debug("Game parametes: name, %s, host %s, port : %s, age %s, nation %s"%(game_name, game_host, game_port, game_age, game_nation))
			gameForm.win.destroy()

			section_values = [
					("section name", game_name),
					("host", game_host),
					("port", game_port),
					("age", game_age),
					("nation", game_nation),
					]
			self.m_cfg.addSection(section_values)
			self.m_cfg.update_cfg()

			#Update game query menu
			pyEyeGUILogger.debug("Calling method to refresh query menu.")
			self.refresh_dynamic_menus()
			# End of add callback handler

		def getGameParams(self):
			pyEyeGUILogger.debug("getGameParams called")
			return {'game':self.game_name, 'host':self.game_host, 'port':self.game_port} 

		gameForm.createForm(okGameForm)




	def remove_game(self):
		pyEyeGUILogger.debug("[py_eye_gui::remove_game()] started")
		#self.m_cfg.update_cfg()
		gameForm = RemoveGameFormCreator()

		def okGameForm():
			items = gameForm.listbox.curselection()
			try:
				items = map(int, items)
			except ValueError: pass

			pyEyeGUILogger.debug("okGameForm for remove game called. Games to remove: %s"%(items))
			#pyEyeGUILogger.debug("remove game %s"%(gameForm.listbox.get(items[0])))

			#Build list of games to remove
			games = []
			for index in items:
				games.append(gameForm.listbox.get(index))
			pyEyeGUILogger.debug("Games to remove: %s"%(games))

			#ToDo, call/add function in cfg class to remove sections of selected games
			self.m_cfg.deleteSections(games)
			gameForm.win.destroy()
			self.m_cfg.update_cfg()

			#Update game query menu
			pyEyeGUILogger.debug("Calling method to refresh query menu.")
			self.refresh_dynamic_menus()
			# End of remove callback handler

		gameForm.createForm(self.m_cfg.m_config.sections(), okGameForm)

	def refresh_settings_menu(self, auto_save="off"):
		pyEyeGUILogger.debug("[py_eye_gui::refresh_settings_menu()] started")
		pyEyeGUILogger.debug("refresh_settings_menu() called. auto_save will be set to %s"%auto_save)

		self.m_menubar.delete(self.m_menubar.index("Settings"))
		self.create_settings_menu(auto_save)

	def refresh_dynamic_menus(self):
		"""
		Refresh dynamic menues made of list of configured games
		"""

		pyEyeGUILogger.debug("[py_eye_gui::refresh_dynamic_menus()] started")

		self.m_menubar.delete(self.m_menubar.index("Query"))
		self.m_menubar.delete(self.m_menubar.index("Play turn"))
		self.m_menubar.delete(self.m_menubar.index("Save turn"))
		gamesmenu = Menu(self.m_menubar, tearoff=0)
		launchmenu = Menu(self.m_menubar, tearoff=0)
		savesmenu = Menu(self.m_menubar, tearoff=0)
		self.m_cfg.update_cfg()

		pyEyeGUILogger.debug("Refreshed game list: %s"%(self.m_cfg.m_config.sections()))

		#for game in self.m_cfg.m_games.keys():
		gamesmenu.add_command(label="Query all", command=self.query_all_games)
		gamesmenu.add_separator()
		for game in self.m_cfg.m_config.sections():
			gamesmenu.add_command(label=game, command= lambda p_game = game: self.query_game(p_game))
			launchmenu.add_command(label=game, command= lambda p_game = game: self.launch_game(p_game))
			savesmenu.add_command(label=game, command= lambda p_game = game: self.save_turn(p_game))
		#self.m_menubar.insert_cascade(2, label="Query", menu=gamesmenu)
		self.m_menubar.insert_cascade(2, label="Query", menu=gamesmenu)
		self.m_menubar.insert_cascade(3, label="Play turn", menu=launchmenu)
		self.m_menubar.insert_cascade(4, label="Save turn", menu=savesmenu)

	def edit_game(self):
		"""
		ToDo, This is very much like add game 
		 only that first a dialog should be displayed to choose game (like delete game form)
		 then this games values should be in the add like form for editing
		"""	

		pyEyeGUILogger.debug("[py_eye_gui::edit_game()] started")
		editSelectForm = EditGameSelectionFormCreator() #Use form for choosing game to edit


		def okEditGameForm():
			items = editSelectForm.listbox.curselection()
			try:
				items = map(int, items)
			except ValueError: pass

			pyEyeGUILogger.debug("okEditGameForm for selecting game to edit is called. game to edit: %s"%(items))
			old_game_name = (editSelectForm.listbox.get(items[0]))
			#pyEyeGUILogger.debug("remove game %s"%(gameForm.listbox.get(items[0])))

			editForm = EditGameFormCreator(self.m_cfg) #Use form for choosing game to edit
			def okEditGame():
				game_name = editForm.entry1.get() 
				pyEyeGUILogger.debug("Game name input: %s"%(game_name)) 
				game_host = editForm.entry2.get() 
				pyEyeGUILogger.debug("Game host input: %s"%(game_host)) 
				game_port = editForm.entry3.get() 
				pyEyeGUILogger.debug("Game port input: %s"%(game_port))
				game_age = editForm.var4.get() 
				pyEyeGUILogger.debug("Game age input: %s"%(game_age))

				pyEyeGUILogger.debug("Game parametes: name, %s, host %s, port : %s, age %s"%(game_name, game_host, game_port, game_age))

				#Get selected nation
				game_nation = editForm.m_nations_listbox.curselection()
				try:
				    game_nation = map(int, game_nation)
				except ValueError: pass

				pyEyeGUILogger.debug("Nation list len: %d, list of selected nations len: %d."%(len(editForm.m_nations_list), len(game_nation)))
				if (len(game_nation) > 0):
					game_nation = editForm.m_nations_list[game_nation.pop()]

				pyEyeGUILogger.debug("Game parametes: name, %s, host %s, port : %s, age %s, nation %s"%(game_name, game_host, game_port, game_age, game_nation))
				editForm.win.destroy()

				section_values = [
						("section name", game_name),
						("host", game_host),
						("port", game_port),
						("age", game_age),
						("nation", game_nation),
						]
				self.m_cfg.deleteSections([old_game_name]) #use items and not game_name. because items is has the value of the old game name in case the game name was also changed. This will prevent a bug of creating duplicate entries with different game names because of edit.
				self.m_cfg.addSection(section_values)
				self.m_cfg.update_cfg()

					#Update game query menu
				pyEyeGUILogger.debug("Calling method to refresh query menu.")
				self.refresh_dynamic_menus()
				# End of edit callback handler

			editForm.createForm(self.m_cfg, editSelectForm.listbox.get(items[0]), okEditGame)



			#self.m_cfg.deleteSections(games)
			editSelectForm.win.destroy()
			self.m_cfg.update_cfg()
#ToDo, here add code for creating the second popup (similiar to add) for editing the chosen game


		editSelectForm.createForm(self.m_cfg.m_config.sections(), okEditGameForm)



	def display_summary_report(self, game_report_list):
		"""
		This function receives a list of (game, nations_list, time_to_host, turn_num ) 
		and display for each game
			#Display:
Game <game>	<nation> <nation icon>	status:[played, not played, AI, server down]	Time to host <time>	Query button	play button	Save button

		ToDo: Consider making this function and display_turn_status() members of a utility class
		and so eliminate duplicate code.
		"""

		pyEyeGUILogger.debug("[py_eye_gui::display_summary_report()] started")

		#location of icons:
		icon_human_control = r"./icons/Master-Joda-48x48.gif"
		icon_AI_control = r"./icons/computer-48x48.gif"
		icon_status_not_played = r"./icons/ErrorCircle-48x48.gif"
		icon_status_played = r"./icons/OKShield-48x48.gif"
		icon_connected = r"./icons/connected-48x48.gif"
		icon_disconnected = r"./icons/disconnected-48x48.gif"
		icon_decorate		= r'./icons/pyeyeicon.gif'
		icon_serv_down		= r'./icons/desable-server-48x48.gif'
		icon_unknown_nation	= r'./icons/help-48x48.gif'

		#Clean up "presentaion" frame from previous displays
		if (self.m_status_frame):
			self.m_status_frame.pack_forget()

		pyEyeGUILogger.debug("[py_eye_gui::display_summary_report()] creating scrollbars")
		#Following is code for allowing vertical and horizontal scroll bars.
		vscrollbar = AutoScrollbar(self.m_root_frame)
		vscrollbar.grid(row=0, column=1, sticky=N+S)
		hscrollbar = AutoScrollbar(self.m_root_frame, orient=HORIZONTAL)
		hscrollbar.grid(row=1, column=0, sticky=E+W)
		

		canvas = Canvas(self.m_root_frame, 
		                yscrollcommand=vscrollbar.set, 
		                xscrollcommand=hscrollbar.set,
				width=900, height=600, bg=self.m_bg, bd=3, relief= GROOVE)
		canvas.grid(row=0, column=0, sticky=N+S+E+W)
		
		vscrollbar.config(command=canvas.yview)
		hscrollbar.config(command=canvas.xview)
		
		# make the canvas expandable
		self.m_root_frame.grid_rowconfigure(0, weight=1)
		self.m_root_frame.grid_columnconfigure(0, weight=1)
		
		# create canvas contents
		self.m_status_frame = Frame(canvas, bg = self.m_bg)
		self.m_status_frame.rowconfigure(1, weight=1)
		self.m_status_frame.columnconfigure(1, weight=1)

		#Display nation icon
		pyEyeGUILogger.debug("[py_eye_gui::display_summary_report()] creating heading")
#		tabLabel = Label(self.m_status_frame, text="			", bg = self.m_bg, font=("Helvetica", 20))
#		tabLabel.grid(row=0, column = 0)

		decor_photo = PhotoImage(file=icon_decorate)
		decor_label1 = Label(self.m_status_frame, image=decor_photo ,bg = self.m_bg)
		decor_label1.photo = decor_photo
		decor_label1.grid(row=0, column=0)
		decor_label2 = Label(self.m_status_frame, image=decor_photo ,bg = self.m_bg)
		decor_label2.photo = decor_photo
		decor_label2.grid(row=0, column=9)

		heading = Label(self.m_status_frame, text="PyEye GAMES REPORT", bg = self.m_bg, font=("Helvetica", 20))
		heading.grid(row=0, column = 1, columnspan=7)

		#Parameters to control the layout of the report
		xcoordinate	= 1
		ycoordinate	= 0
		rowsize		= 1 #This controls how many nation reports per line
		rowindex	= 0
		rowspan_val	= 1
		padx_val	= 1
		pady_val	= 5

		#Layout the report
		for game_report in game_report_list:
			nation_found = False
			(game, nations_list, time_to_host, turn_num ) = game_report
			pyEyeGUILogger.debug("[py_eye_gui::display_summary_report()] displaying report for: game %s, nations list %s, time to host %s, turn %s"%(game, nations_list, time_to_host, turn_num ))


			#Display game name
			game_label = Label(self.m_status_frame, text="%-20s"%(game) ,  bg = self.m_bg, font=("Helvetica", 16))
			game_label.grid(row=xcoordinate, column=ycoordinate)
			pyEyeGUILogger.debug("[py_eye_gui::display_summary_report()] label position, row %d, col %d,"%(xcoordinate, ycoordinate))

			if nations_list == 0: #Error, server is down or wrong configuration
				pyEyeGUILogger.info("[py_eye_gui::display_summary_report()] Server of game %s is not reachable or wrongly configured"%(game))

			#ToDO:
			#1. remove the server is unreachable message and make it a tooltip instead [done]
			#2. add tooltips for nation (all data) and for unknown nation
			#3. Add time to host and turn # and buttons (query, play, save)
			#4. Fix layout issues, make the report heading a frame and then pack it directly into master frame top!
			# Also add padx for the buttons
			#5. make exe for windows and distutil
				#Label, server is down
				#serv_down_lbl = Label(self.m_status_frame, text="%-20s"%('Server is unreachable') ,  bg = self.m_bg, font=("Helvetica", 16))
				#ycoordinate = ycoordinate +2
				#serv_down_lbl.grid(row=xcoordinate, column=ycoordinate)

				serv_down_photo = PhotoImage(file=icon_serv_down)
				serv_down_lbl1 = Label(self.m_status_frame, image=serv_down_photo ,bg = self.m_bg)
				serv_down_lbl1.photo = serv_down_photo
				ycoordinate = ycoordinate +2
				serv_down_lbl1.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
				tooltip1 = ToolTip(serv_down_lbl1, text="%-20s"%('Server is unreachable'))
			else: #valid nation information received from dominions server
			#Process nation, check if correctly configured and is in list of nations participating in the game
				#Display nation icon
				#Extract nation info
				nation = (self.m_cfg.m_games[game].m_nation)
				pyEyeGUILogger.debug("Player nation for game %s is %s"%(game, nation))

				if nation == 'unknown': #This happens when nation parameter is not configured for the game
					pass #Do nothing, since nation_found is defaulted to False
					#ToDo, display a question mark icon for nation and label it unknown
				else: #Nation configuration for game exists
					for n in nations_list:
						if n.m_name == nation:
							nation_found = True
							nation_photo = PhotoImage(file=r"./icons/"+n.m_icon)
							nation_label2 = Label(self.m_status_frame, image=nation_photo ,bg = self.m_bg)
							nation_label2.photo = nation_photo
							ycoordinate = ycoordinate +2
							nation_label2.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
							tooltip3 = ToolTip(nation_label2, text="Nation %s, Controled %s, Status %s, %s, Timer: %dh:%dm, Turn, %s"%(nation, n.m_controled, n.m_status, n.m_con, time_to_host/60, time_to_host%60, turn_num ))
							#Display controlled icon
							control_photo = 0
							if n.m_controled == 'human': #human player
								control_photo = PhotoImage(file=icon_human_control)
							elif n.m_controled == 'AI': #AI 
								control_photo = PhotoImage(file=icon_AI_control)
								# NOTE, AI nations are always in 'played' and 'connected' state so set them up as such:
								n.m_status = 'played'
								n.m_con	= 'connected'

							else:
								pyEyeLogger.error( "Illegel control status %s for nation %s."%( n.m_controled, n.m_name))

							#Cont. display of controlled icon...
							nation_label3 = Label(self.m_status_frame, image=control_photo, bg = self.m_bg)
							nation_label3.photo = control_photo
							ycoordinate = ycoordinate +1
							nation_label3.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val)
							tooltip4 = ToolTip(nation_label3, text='Nation is controlled by '+n.m_controled)

							#Display status icon
							status_photo = 0
							if (n.m_status == 'played' ): 
								status_photo = PhotoImage(file=icon_status_played)
							elif n.m_status == 'not played': 
								status_photo = PhotoImage(file=icon_status_not_played)
							else:
								pyEyeLogger.error( "Illegel played status %s for nation %s."%( n.m_status, n.m_name))
							nation_label4 = Label(self.m_status_frame, image=status_photo, bg = self.m_bg)
							nation_label4.photo = status_photo
							ycoordinate = ycoordinate +1
							nation_label4.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val)
							tooltip5 = ToolTip(nation_label4, text='Turn '+n.m_status)

							#Display connected icon
							conncected_photo = 0
							if (n.m_con== 'connected' ): 
								conncected_photo = PhotoImage(file=icon_connected)
							elif n.m_con== 'not connected': 
								conncected_photo = PhotoImage(file=icon_disconnected)
							else:
								pyEyeLogger.error( "Illegel played conncected %s for nation %s."%( n.m_conncected, n.m_name))
							nation_label5 = Label(self.m_status_frame, image=conncected_photo, bg = self.m_bg)
							nation_label5.photo = conncected_photo
							ycoordinate = ycoordinate +1
							nation_label5.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val)
							tooltip6 = ToolTip(nation_label5, text='Player is '+n.m_con)



				if nation_found == False: #Either nation was not configured ('unknown') or is not in the list of participating nations
					pyEyeGUILogger.info("[py_eye_gui::display_summary_report()] Nation parameter is mis/not configured for game %s"%(game))
					nation_photo = PhotoImage(file=icon_unknown_nation)
					nation_label2 = Label(self.m_status_frame, image=nation_photo ,bg = self.m_bg)
					nation_label2.photo = nation_photo
					ycoordinate = ycoordinate +2
					nation_label2.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
					tooltip2 = ToolTip(nation_label2, text="Nation parameter is mis/not configured for game %s"%(game))
#					missing_nation_label = Label(self.m_status_frame, text="		",  bg = self.m_bg, font=("Helvetica", 16))
#					ycoordinate = ycoordinate +1
#					missing_nation_label.grid(row=xcoordinate, column=ycoordinate)

				
				#Display turn #
				turn_no_label = Label(self.m_status_frame, text="Turn: %s"%(turn_num) ,  bg = self.m_bg, font=("Helvetica", 16))
				ycoordinate = ycoordinate +1
				turn_no_label.grid(row=xcoordinate, column=ycoordinate)

				#Display time to host
				time_to_host_label = Label(self.m_status_frame, text="Timer: %dh:%dm"%(time_to_host/60, time_to_host%60) ,  bg = self.m_bg, font=("Helvetica", 16))
				ycoordinate = ycoordinate +1
				time_to_host_label.grid(row=xcoordinate, column=ycoordinate)


				#Query button
				query_button = Button(self.m_status_frame, text="Query", command= lambda p_game = game: self.query_game(p_game))
				ycoordinate = ycoordinate +1
				query_button.grid(row=xcoordinate, column=ycoordinate, padx=3)
				tooltip3 = ToolTip(query_button, text="Query %s server"%(game))

				#play button
				play_button = Button(self.m_status_frame, text="Play", command= lambda p_game = game: self.launch_game(p_game))
				ycoordinate = ycoordinate +1
				play_button.grid(row=xcoordinate, column=ycoordinate, padx=3)
				tooltip4 = ToolTip(play_button, text="Launch game %s"%(game))

				#save turn button
				save_button = Button(self.m_status_frame, text="Save", command= lambda p_game = game: self.save_turn(p_game))
				ycoordinate = ycoordinate +1
				save_button.grid(row=xcoordinate, column=ycoordinate, padx=3, sticky=W)
				tooltip5 = ToolTip(save_button, text="Save turn %s of game %s"%(turn_num, game))

			#Display rowsize reports per row:
			rowindex = rowindex +1
			if (rowindex%rowsize == 0): #new row
				xcoordinate = xcoordinate+2
				ycoordinate = 0
			else: #Advance the y coordinate
				ycoordinate = ycoordinate +2

			#End of game_report loop

		#Make the canvas and its contents visible on main frame
		canvas.create_window(0, 0, anchor=NW, window=self.m_status_frame)
		self.m_status_frame.update_idletasks()
		canvas.config(scrollregion=canvas.bbox("all"))
		
	def display_turn_status(self, game, nations_list, time_to_host, turn_num):
		"""
		This function receives a list of pyEyeNationCfg instances that contain
		status of current turn. It then displays them on root frame.
		It also receives the game name for displaying it and the game age.
		"""

		pyEyeGUILogger.debug("[py_eye_gui::display_turn_status()] started")

		#location of icons:
		icon_human_control = r"./icons/Master-Joda-48x48.gif"
		icon_AI_control = r"./icons/computer-48x48.gif"
		icon_status_not_played = r"./icons/ErrorCircle-48x48.gif"
		icon_status_played = r"./icons/OKShield-48x48.gif"
		icon_connected = r"./icons/connected-48x48.gif"
		icon_disconnected = r"./icons/disconnected-48x48.gif"

		#nation = nations_list[0]
#		self.m_cfg.m_games[game].m_name
#		self.m_cfg.m_games[game].m_age

		#Clean up "presentaion" frame from previous displays
		if (self.m_status_frame):
			self.m_status_frame.pack_forget()


		#Following is code for allowing vertical and horizontal scroll bars.
		vscrollbar = AutoScrollbar(self.m_root_frame)
		vscrollbar.grid(row=0, column=1, sticky=N+S)
		hscrollbar = AutoScrollbar(self.m_root_frame, orient=HORIZONTAL)
		hscrollbar.grid(row=1, column=0, sticky=E+W)
		
		canvas = Canvas(self.m_root_frame, 
		                yscrollcommand=vscrollbar.set, 
		                xscrollcommand=hscrollbar.set,
				width=900, height=600, bg=self.m_bg, bd=3, relief= GROOVE)
		canvas.grid(row=0, column=0, sticky=N+S+E+W)
		
		vscrollbar.config(command=canvas.yview)
		hscrollbar.config(command=canvas.xview)
		
		# make the canvas expandable
		self.m_root_frame.grid_rowconfigure(0, weight=1)
		self.m_root_frame.grid_columnconfigure(0, weight=1)
		
		# create canvas contents
		self.m_status_frame = Frame(canvas, bg = self.m_bg)
		self.m_status_frame.rowconfigure(1, weight=1)
		self.m_status_frame.columnconfigure(1, weight=1)

		#self.m_status_frame = Frame(self.m_root_frame, bg = self.m_bg)

		heading = Label(self.m_status_frame, text=" %s, Turn %d, Timer: %dh:%dm"%(game, turn_num, time_to_host/60, time_to_host%60), bg = self.m_bg, font=("Helvetica", 16))
		heading.grid(row=0, column = 3, columnspan=20)
		#heading.pack(side=TOP)

		xcoordinate	= 1
		ycoordinate	= 0
		rowsize		= 3
		rowindex	= 0
		rowspan_val	= 1
		padx_val	= 1
		pady_val	= 5

		for nation in nations_list:
			pyEyeLogger.info( "Adding label for nation: %s in coordinsates [%d, %d] while rowindex is %d.. Current dir is %s."%( nation.m_name, xcoordinate, ycoordinate, rowindex, os.getcwd()))

			#Display nation name
			nation_label1 = Label(self.m_status_frame, text=nation.m_name,  bg = self.m_bg)
			nation_label1.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)

			#Display nation icon
			nation_photo = PhotoImage(file=r"./icons/"+nation.m_icon)
			nation_label2 = Label(self.m_status_frame, image=nation_photo ,bg = self.m_bg)
			nation_label2.photo = nation_photo
			ycoordinate = ycoordinate +2
			nation_label2.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)

			#Display controlled icon
			control_photo = 0
			if nation.m_controled == 'human': #human player
				control_photo = PhotoImage(file=icon_human_control)
			elif nation.m_controled == 'AI': #AI 
				control_photo = PhotoImage(file=icon_AI_control)
				# NOTE, AI nations are always in 'played' and 'connected' state so set them up as such:
				nation.m_status = 'played'
				nation.m_con	= 'connected'

			else:
				pyEyeLogger.error( "Illegel control status %s for nation %s."%( nation.m_controled, nation.m_name))

			#Set the tooltip for the nation icon
			tooltip2 = ToolTip(nation_label2, text="[Nation %s, control %s, turn %s, %s]"%(nation.m_name, nation.m_controled, nation.m_status, nation.m_con))

			#Cont. display of controlled icon...
			nation_label3 = Label(self.m_status_frame, image=control_photo, bg = self.m_bg)
			nation_label3.photo = control_photo
			ycoordinate = ycoordinate +2
			nation_label3.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
			tooltip3 = ToolTip(nation_label3, text='Nation is controlled by '+nation.m_controled)

			#Display status icon
			status_photo = 0
			if (nation.m_status == 'played' ): 
				status_photo = PhotoImage(file=icon_status_played)
			elif nation.m_status == 'not played': 
				status_photo = PhotoImage(file=icon_status_not_played)
			else:
				pyEyeLogger.error( "Illegel played status %s for nation %s."%( nation.m_status, nation.m_name))
			nation_label4 = Label(self.m_status_frame, image=status_photo, bg = self.m_bg)
			nation_label4.photo = status_photo
			ycoordinate = ycoordinate +2
			nation_label4.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
			tooltip4 = ToolTip(nation_label4, text='Turn '+nation.m_status)

			#Display connected icon
			conncected_photo = 0
			if (nation.m_con== 'connected' ): 
				conncected_photo = PhotoImage(file=icon_connected)
			elif nation.m_con== 'not connected': 
				conncected_photo = PhotoImage(file=icon_disconnected)
			else:
				pyEyeLogger.error( "Illegel played conncected %s for nation %s."%( nation.m_conncected, nation.m_name))
			nation_label5 = Label(self.m_status_frame, image=conncected_photo, bg = self.m_bg)
			nation_label5.photo = conncected_photo
			ycoordinate = ycoordinate +2
			nation_label5.grid(row=xcoordinate, column=ycoordinate, rowspan=rowspan_val, padx=padx_val, pady=pady_val)
			tooltip5 = ToolTip(nation_label5, text='Player is '+nation.m_con)









			#Display rowsize nations per row:
			rowindex = rowindex +1
			if (rowindex%rowsize == 0): #new row
				xcoordinate = xcoordinate+2
				ycoordinate = 0
			else: #Advance the y coordinate
				ycoordinate = ycoordinate +2

		canvas.create_window(0, 0, anchor=NW, window=self.m_status_frame)
		self.m_status_frame.update_idletasks()
		canvas.config(scrollregion=canvas.bbox("all"))
		#self.m_status_frame.pack()
		
	def display_server_down(self, game):
		"""
		Display a message that the dominons server in question is unreachable
		"""

		pyEyeGUILogger.debug("[py_eye_gui::display_server_down()] started")

		if (self.m_status_frame):
			self.m_status_frame.pack_forget()
		
		self.m_status_frame = Frame(self.m_root_frame, bg = self.m_bg)
		heading = Label(self.m_status_frame, 
					text= "Dominions server %s is down!"%(self.m_cfg.m_games[game].m_host),
					bg = self.m_bg, 
					font=("Helvetica", 32))
		heading.pack()


		icon_server_down = r"./icons/desable-server-128x128.gif"
		server_down_photo = PhotoImage(file=r""+icon_server_down)
		server_down_label = Label(self.m_status_frame, image=server_down_photo ,bg = self.m_bg)
		server_down_label.photo = server_down_photo
		server_down_label.pack()
		tooltip = ToolTip(server_down_label, text="Dominions server %s is down!"%(self.m_cfg.m_games[game].m_host))
		self.m_status_frame.pack(side=TOP)	

	def save_turn(self, game):
		"""
		This function saves the current turn of the given game
		"""

		pyEyeGUILogger.debug("[py_eye_gui::save_turn()] started")

		pyEyeGUILogger.info("Saving turn of game: %s."%(game))
		pyEyeGUILogger.debug("Turn will be saved to: %s."%(self.m_cfg.m_settings['backup_path']))

#		#Save game routine:
		dom_util = DomIIIUtils(self.m_cfg)
		turn = dom_util.save_turn_for_client(game)

	
		if turn == None:
			#Fail message
			pyEyeGUILogger.debug("Displaying turn saved failed dialog")
			backup_msg = "Failed to save turn of game %s"%(game)
			SimpleDialog(self.m_master,
			text=backup_msg,
			buttons=["OK"],
			default=0,
			title="Turn save failed!").go()
		else: 
			#Success message
			pyEyeGUILogger.debug("Displaying turn saved dialog")
			backup_msg = "Saved turn %s of game %s"%(turn, game)
			SimpleDialog(self.m_master,
			text=backup_msg,
			buttons=["OK"],
			default=0,
			title="Turn saved").go()
# End of save_turn()

		"""
		 This is first attempt to spawn game in new thread.
		 It wasn't successful. 
		 Todo, attempt to create a new class, gameLauncher that 
		 inherits from threading.Thread. See example below:

		import threading

class mythread(threading.Thread):          # subclass Thread object
    def _ _init_ _(self, myId, count):
        self.myId  = myId
        self.count = count
        threading.Thread._ _init_ _(self)
    def run(self):                         # run provides thread logic
        for i in range(self.count):        # still sync stdout access
            stdoutmutex.acquire( )
            print '[%s] => %s' % (self.myId, i)
            stdoutmutex.release( )

stdoutmutex = threading.Lock()              # same as thread.allocate_lock( )
threads = []
for i in range(10):
    thread = mythread(i, 100)                # make/start 10 threads
    thread.start( )                         # start run method in a thread
    threads.append(thread)

for thread in threads:
    thread.join( )                          # wait for thread exits
print 'Main thread exiting.'

		"""
#	def launch_game_in_thread(self, game):
#		"""
#		This function calls up dominions III to connect to given game server
#		"""
#
#		gamemutex.acquire( )
#
#		pyEyeGUILogger.info("Launching Game: %s."%(game))
#		pyEyeGUILogger.debug("Dom path %s, flags %s, host %s, port %s"%(self.m_cfg.m_settings['dom_path'], self.m_cfg.m_settings['dom_flags'], self.m_cfg.m_games[game].m_host,self.m_cfg.m_games[game].m_port))
#
#		#create a thread for launching dom III
#		exe_path = self.m_cfg.m_settings['dom_path']
#		#exe_path = exe_path.replace(' ', '\ ')
#		cur_dir = os.getcwd()
#		os.chdir(os.path.dirname(exe_path))
#		cmd = os.path.basename(exe_path)+ ' '+ self.m_cfg.m_settings['dom_flags']+ '  -C --ipadr '+ self.m_cfg.m_games[game].m_host+ ' --port '+ self.m_cfg.m_games[game].m_port 
#		cmd = "%s"%(cmd)
#				 
#		pyEyeGUILogger.debug("Initiating dominions III client with command %s"%(cmd))
#		os.system(cmd)
#		os.chdir(cur_dir)
#
#		gamemutex.release( )
#		exitmutexes[1].acquire( )
#
#	def launch_game(self, game):
#		"""
#		This function is a wrapper for launching a game in a separate thread 
#		"""
#		pyEyeGUILogger.info("Spawning thread for launching game: %s."%(game))
#		gamemutex = thread.allocate_lock( )
#		exitmutexes = []
#		exitmutexes.append(thread.allocate_lock( ))
#
#		thread.start_new(self.launch_game, (game,))
#
#		for mutex in exitmutexes:
#			while not mutex.locked( ): pass

	def launch_game(self, game):
		"""
		This function calls up dominions III to connect to given game server
		"""

		pyEyeGUILogger.info("Launching Game: %s."%(game))
		pyEyeGUILogger.debug("Dom path %s, flags %s, host %s, port %s"%(self.m_cfg.m_settings['dom_path'], self.m_cfg.m_settings['dom_flags'], self.m_cfg.m_games[game].m_host,self.m_cfg.m_games[game].m_port))

		#create a thread for launching dom III
		exe_path = self.m_cfg.m_settings['dom_path']
		#exe_path = exe_path.replace(' ', '\ ')
		cur_dir = os.getcwd()
		os.chdir(os.path.dirname(exe_path))
		cmd = os.path.basename(exe_path)+ ' '+ self.m_cfg.m_settings['dom_flags']+ '  -C --ipadr '+ self.m_cfg.m_games[game].m_host+ ' --port '+ self.m_cfg.m_games[game].m_port 
		cmd = "%s"%(cmd)
				 
		pyEyeGUILogger.debug("Initiating dominions III client with command %s"%(cmd))
		#Note, The "&" at the end will make it run in the background 
		# but only under Linux, Cygwin, Unix etc.
		# Spawning a thread isn't possible because of the os.system() in thread issue.
		#os.system(cmd+"&")
		try: 
			if os.name == 'nt':
				os.system("start "+cmd)
			else:#posix, unix
				os.system(cmd+"&")
		except os.error:
			pyEyeGUILogger.warning("Couldn't launch dominions game %s using cmd %s"%(game, cmd))
		except IOError, (errno, strerror):
			pyEyeGUILogger.warning("Couldn't launch dominions game %s using cmd %s. I/O error(%s): %s"%(game, cmd, errno, strerror))
		except:
			pyEyeGUILogger.warning("Couldn't launch dominions game %s using cmd %s"%(game, cmd))


		#See if auto save is required
		if (self.m_is_auto_save == "on"):
			self.save_turn(game)
#		### Thread attempt
#		#Currently there is some issue that calls to os.system cause the thread to die 
#		background = DomIIIRunner(cmd)
#		pyEyeGUILogger.debug("Spawning thread for dominions III client with command %s"%(cmd))
#		background.start()
#		pyEyeGUILogger.debug("Dom III game thread spawned")
#    
#		background.join()    # Wait for the background task to finish
#		### Thread attempt
		os.chdir(cur_dir)

	def query_all_games(self):
		"""
		Query the results of all configured games and display them in summary report
		"""

		pyEyeGUILogger.debug("query_all_games starting")

		games_report_list = []
		for game in self.m_cfg.m_config.sections():
			#Todo, call self.query_game(), collect results and 
			# add a function to display them
			# Also add to game configuration nation field
			(game, nations_list, time_to_host, turn_num ) = self.query_game(game, False)
			pyEyeGUILogger.info("Adding entry to games report list Game: %s, nations: %s, time to host: %s, turn: %s"%(game, nations_list, time_to_host, turn_num ))
			games_report_list.append((game, nations_list, time_to_host, turn_num ))

		self.display_summary_report(games_report_list)
			#ToDo, resolve issues when server is down.


	def query_game(self, game, display = True):
		"""
		This function calls up the pyEye dominions III client to check on the status of the current
		turn.
		"""
		pyEyeGUILogger.debug("Game: %s)"%(game))
		self.m_cfg.update_cfg()

		client = Dom3Client(self.m_cfg.m_games[game].m_host,self.m_cfg.m_games[game].m_port, 1024)
		nations_list, time_to_host, turn_num = client.parse_query_response_gui(client.send_data(client.build_player_query()), self.m_cfg)

		if (nations_list == 0):#only happens when dominions server wasn't reachable
			pyEyeLogger.info( "Dominions server %s is down"%(self.m_cfg.m_games[game].m_host))
			if display:
				self.display_server_down(game)
			else:
				return (game, nations_list, time_to_host, turn_num )
			#return 0
		else: #Successful query
			pyEyeGUILogger.debug("Time to next host: %4d hours, %2d minuts, turn %d"%(time_to_host/60, time_to_host%60, turn_num) )

			for nation in nations_list:
				pyEyeGUILogger.info("Nation status: %s)"%(nation))
			#ToDo, add function to display results

			if display:
				self.display_turn_status(game, nations_list, time_to_host, turn_num )
			else:
				return (game, nations_list, time_to_host, turn_num )

	def games(self):
		pyEyeGUILogger.debug("Games: %s)"%(self.m_cfg.m_games.keys()))
		SimpleDialog(self.m_master,
		text=(self.m_cfg.m_games.keys()),
		buttons=["OK"],
		default=0,
		title="About PyEye").go()

	def set_auto_save(self):
		pyEyeGUILogger.debug("Setting auto save. Current setting is %s"%self.m_is_auto_save)
		
		auto_save = "off"
		if self.m_is_auto_save == "off":
			auto_save = "on"
			self.m_is_auto_save = "on"
		elif self.m_is_auto_save == "on": 
			auto_save = "off"
			self.m_is_auto_save = "off"

		self.m_cfg.update_settings_cfg(auto_save_turns=auto_save)
		self.refresh_settings_menu(auto_save)

	def set_backup_path(self):
		#Following code is for selecting the directory via a string
		# such as "c:\temp"
#		backup_path = askstring(title='Turns backup path',
#				prompt='Please enter location to which you would like your turns to be saved',
#				initialvalue=self.m_cfg.m_settings['backup_path']
#				)

		#Following code is for selecting the directory via a directory 
		# chooser dialog
		backup_path = askdirectory( title="Please select directory to contain saved turns", mustexist=1)

		if not backup_path:
			pyEyeGUILogger.debug("Setting Dom III backup path was canceled by user")
		else:
			pyEyeGUILogger.info("Setting Dom III turns backup location to: %s"%(backup_path))
			self.m_cfg.update_settings_cfg(backup_path=backup_path)


	def set_dom_flags(self):
		dom_flags = askstring(title='Dom Flags',
				prompt='Please enter your prefered dominions flags',
				initialvalue=self.m_cfg.m_settings['dom_flags']
				)
		if dom_flags !=None:
			pyEyeGUILogger.info("Setting Dom III exe flags to: %s"%(dom_flags))
			self.m_cfg.update_settings_cfg(flags=dom_flags)
		else:
			pyEyeGUILogger.debug("Setting Dom III exe flags was canceled by user")



	def set_dom_path(self):
		dom_exe_path = askopenfilename( defaultextension = '.exe',
						initialdir =r'c:/Program Files/dominions3/' ,
						title='Please choose dom III exe')

		if dom_exe_path != None:
			pyEyeGUILogger.info("Setting Dom III exe path to: %s"%(dom_exe_path))
			self.m_cfg.update_settings_cfg(path=dom_exe_path)
		else:
			pyEyeGUILogger.debug("Setting Dom III exe path was canceled by user")


	def usage(self):
		"""
		For help->usage submenu
		"""

		pyEyeGUILogger.debug("Displaying usage dialog")

		# pop up a dialog window usage text

		usage_text="""Usage:
		Games menu allows to add/remove/edit games.
		Query menu allows to query status of game servers
		Save menu allows to save current turn for later replay or review


		To save the turn files you first need to configure settings->set turns backup path, then before/after playing your turn hit the save turn->your game and the turn will be saved.

		Use settings to configure path to dom-III exe on your system and whatever flags you'd like for it to use. Then use "Play turn"->your game to connect to your game server.

		More information can be found at the corresponding Shrapned forums thread: http://www.shrapnelcommunity.com/ at dominions III "Illwinter Game Design  >> Dominions 3: The Awakening >> Scenarios, Maps and Mods >> GUI for probing turn status"
		"""
		SimpleDialog(self.m_master,
		text=usage_text,
		buttons=["OK"],
		default=0,
		title="PyEye Usage").go()

	def about(self):
		"""
		For help->about submenu
		"""
		pyEyeGUILogger.debug("PyEye GUI.\nCreated by Yosi Izaq (aka Wraithlord).\n\nMany thanks to Zepath for the beautiful nation icons.\nThanks to Shrapnel games for hosting dominions forums\nAnd last but not least, thank you IW for giving us this gem of a game!")

		d = AboutDialog(self.m_master, self.m_version)
		self.m_master.wait_window(d.top)


#main
if __name__ == '__main__':
	pyEyeGUILogger.debug("Starting PyEyeGUI") 

	#Note, following code attached a costum icon for PyEyeGUI.
	root = Tk()

	try:
		if os.name == 'nt':
			root.iconbitmap(default=r'./icons/pyeyeicon.ico')
		else: #unix, posix
			root.iconbitmap('./icons/pyeyeicon.ico')
	except:           
		pyEyeGUILogger.error("Caught exception ", (sys.exc_info()))

	#Label(root, text='This window now has a custom icon.').pack()

	#t = Toplevel(tk)
	#Label(t, text='This one has the same custom icon.').pack()


	#root = Tk()
	pyEyeGUILogger.debug("Created Tkinter instance.") 
	gui = pyEyeGui(root)
	#Label(root, text='This one has the same custom icon.').pack()
	pyEyeGUILogger.debug("Created GUI instance.") 
	root.mainloop()
