#!/usr/bin/python

from wxPython.wx import *
from wxPython.xrc import *
from sabregl import *
from threading import Thread
from socket import *
from myrgame import Game
from ConfigParser import SafeConfigParser
import time, sys

class CharacterViewer(Thread):
	
	def __init__(self):
		Thread.__init__(self)
		initscreen(300, 400, 16)
		framerate(100)
		self.running = 1
		       
	def model(self, model):
		loadmd2(0, model + ".md2", [0, 0, -6])
		scale(0, 0.07, 0.07, 0.07)
		rotate(0, 270, [1, 0, 0])
		speed(0, 5)
		texture(0, model + ".bmp")
		
	def shutdown(self):
		self.running = 0
		
	def run(self):
		while self.running:
			sync()
			time.sleep(0.0001)
		shutdown()


class Myrmidia(wxApp):
	def OnInit(self):
		self.res = wxXmlResource("interface.xml")
		self.version = 0.1
		wxInitAllImageHandlers()
		self.initFrame()
		self.initEvents()
		return True

	def initFrame(self):
		self.frame = self.res.LoadFrame(None, "frmMenu")
		self.frame.Show()
		self.SetTopWindow(self.frame)

	def initEvents(self):
		EVT_BUTTON(self, XRCID("btnLogin"), self.login)
		EVT_BUTTON(self, XRCID("btnCreate"), self.create)
		EVT_BUTTON(self, XRCID("btnPrefs"), self.prefs)
		EVT_BUTTON(self, XRCID("btnQuit"), self.quit)

	def login(self, event):
		self.login = self.res.LoadFrame(self.frame, "frmLogin")
		EVT_BUTTON(self.login, XRCID("btnOkay"), self.okayLogin)
		EVT_BUTTON(self.login, XRCID("btnCancel"), self.closeLogin)
		self.login.Show()
		self.frame.Disable()

	def closeLogin(self, event):
		self.login.Close()
		self.frame.Enable(1)

	def okayLogin(self, event):
		username = XRCCTRL(self.login, "txtName").GetValue()
		password = XRCCTRL(self.login, "txtPass").GetValue()
		if not username or not password:
			dlg = wxMessageDialog(self.login, "You must fill in all the fields.", "Myrmidia - Input Error", wxOK | wxICON_HAND)
			dlg.ShowModal()
			return
		if self.connect():
			self.sock.send("LOGIN|" + username + "|" + password + "\n")
			data = self.sock.recv(1024)
			if (data[:6]=="ERROR|"):
				dlg = wxMessageDialog(self.login, data[6:], "Myrmidia - Login Error", wxOK | wxICON_HAND)
				dlg.ShowModal()
				self.sock.close()
				return
			if (data[:8]=="SUCCESS|"):
				self.closeLogin(event)
				self.frame.Hide()
				self.game = Game(self.sock, username, self)
				self.game.MainLoop()

	def create(self, event):
		self.create = self.res.LoadFrame(self.frame, "frmCreate")
		self.create.Show()
		#self.viewer = CharacterViewer()
		#self.viewer.model('Ogre')
		#self.viewer.start()
		EVT_BUTTON(self.create, XRCID("btnOkay"), self.okayCreate)
		EVT_BUTTON(self.create, XRCID("btnCancel"), self.closeCreate)
		EVT_CHOICE(self.create, XRCID("chcModel"), self.changeModel)
		EVT_CLOSE(self.create, self.closeCreate)
		self.frame.Disable()

	def okayCreate(self, event):
		username = XRCCTRL(self.create, "txtName").GetValue()
		password = XRCCTRL(self.create, "txtPass").GetValue()
		passconf = XRCCTRL(self.create, "txtConf").GetValue()
		email = XRCCTRL(self.create, "txtEmail").GetValue()
		appearance = XRCCTRL(self.create, "chcModel").GetStringSelection()
		if (not username or not password or not email): # or not appearance):
			dlg = wxMessageDialog(self.create, "You must fill in all the fields.", "Myrmidia - Input Error", wxOK | wxICON_HAND)
			dlg.ShowModal()
			return
		if (password != passconf):
			dlg = wxMessageDialog(self.create, "Your passwords do not match.", "Myrmidia - Password Error", wxOK | wxICON_HAND)
			dlg.ShowModal()
			return
		if (self.connect()):
			self.sock.send("CREATE|" + username + "|" + password + "|" + email + "|" + appearance + "\n")
			data = self.sock.recv(1024)
			if data[:6]=="ERROR|":
				dlg = wxMessageDialog(self.create, data[6:], "Myrmidia - Creation Error", wxOK | wxICON_HAND)
				dlg.ShowModal()
				self.sock.close()
			if data[:8]=="SUCCESS|":
				dlg = wxMessageDialog(self.create, data[8:], "Myrmidia - Character Created", wxOK | wxICON_INFORMATION)
				dlg.ShowModal()
		self.closeCreate(event)

	def closeCreate(self, event):
		#self.viewer.shutdown()
		self.create.Destroy()
		self.frame.Enable(1)

	def prefs(self, event):
		self.prefs = self.res.LoadFrame(self.frame, "frmPrefs")
		EVT_BUTTON(self.prefs, XRCID("btnCancel"), self.cancelPrefs)
		EVT_BUTTON(self.prefs, XRCID("btnOkay"), self.okayPrefs)
		EVT_CLOSE(self.prefs, self.closePrefs)
		self.txtServer = XRCCTRL(self.prefs, "txtServer")
		self.txtPort = XRCCTRL(self.prefs, "txtPort")
		self.ckbAudio = XRCCTRL(self.prefs, "ckbAudio")
		self.chcRes = XRCCTRL(self.prefs, "chcRes")
		self.chcDepth = XRCCTRL(self.prefs, "chcDepth")
		try:
			self.config = SafeConfigParser()
			self.config.read("myrmidia.conf")
			#Server
			server = self.config.get("Server", "host")
			port = self.config.get("Server", "port")
			self.txtServer.SetValue(server)
			self.txtPort.SetValue(port)
			#Graphics
			resolution = self.config.get("Graphics", "resolution")
			self.chcRes.SetStringSelection(resolution)
			depth = self.config.get("Graphics", "depth")
			self.chcDepth.SetStringSelection(depth)
			#Audio
			audio = str.lower(self.config.get("Audio", "enabled"))
			if audio == "true":
				self.ckbAudio.SetValue(1)
		except:
			print "Error loading config, creating defaults."
			#Set defaults
			self.txtServer.SetValue("server.myrmidia.com")
			self.txtPort.SetValue("2300")
			self.config = SafeConfigParser()
			self.config.set("Server", "host", "server.myrmidia.com")
			self.config.set("Server", "port", "2300")
			self.config.set("Graphics", "resolution", "800x600")
			self.config.set("Graphics", "depth", "16")
			self.config.set("Audio", "enabled", "true")
			self.config.set("Audio", "mixer", "true")
		self.prefs.Show()
		self.frame.Disable()

	def okayPrefs(self, event):
		self.config.set("Server", "host", self.txtServer.GetValue())
		self.config.set("Server", "port", self.txtPort.GetValue())
		self.config.set("Graphics", "resolution", self.chcRes.GetStringSelection())
		self.config.set("Graphics", "depth", self.chcDepth.GetStringSelection())
		
		if self.ckbAudio.GetValue() == 1:
			self.config.set("Audio", "enabled", "true")
		else:
			self.config.set("Audio", "enabled", "false")
		self.config.write(open("myrmidia.conf", "w"))
		self.prefs.Close()

	def cancelPrefs(self, event):
		self.prefs.Close()

	def closePrefs(self, event):
		self.prefs.Destroy()
		self.frame.Enable(1)

	def changeModel(self, event):
		chcModel = XRCCTRL(self.create, "chcModel")
		model = chcModel.GetStringSelection()
		#self.viewer.model(model)
		
	def connect(self):
		try:
			config = SafeConfigParser()
			config.read("myrmidia.conf")
			server = config.get("Server", "host")
			port = int(config.get("Server", "port"))
			self.sock = socket(AF_INET, SOCK_STREAM)
			self.sock.connect((server, port))
		except:
			dlg = wxMessageDialog(self.frame, "Sorry, I could not connect to the server. Please check the website to make sure it is online before asking for help on the forums.", "Myrmidia - Connection Error", wxOK | wxICON_HAND)
			dlg.ShowModal()
			return None
		data = self.sock.recv(1024)
		serverVersion = float(data[len(data) - 3:])
		if(serverVersion > self.version):
			dlg = wxMessageDialog(self.frame, "Sorry, your client is out of date. Please download the latest version from http://www.myrmidia.com", "Myrmidia - Version Mismatch", wxOK | wxICON_HAND)
			dlg.ShowModal()
			return None
		return 1

	def quit(self, event=None):
		self.frame.Close()
		sys.exit(0)

if __name__ == '__main__':
	app = Myrmidia()
	app.MainLoop()
