import wx , os

#Gui and main class
class MainGui(wx.Frame):

	#--------------------------------------------------------------------------------

	def __init__(self,parent,id):

		#create the frame
		wx.Frame.__init__(self,parent,id,'Obfuse v0.1',size = (340,260),style=wx.DEFAULT_FRAME_STYLE ^ wx.RESIZE_BORDER ^ wx.MAXIMIZE_BOX)

		#create the panel
		panel = wx.Panel(self);

		#create an instance of the cipher systems class
		self.cipherSys = CipherSys()

		sampleList = []

		#list object
		lb = wx.ListBox(panel,pos = (10,100), size = (300,100), choices = sampleList)

		#cipher button
		self.cipherButton = wx.Button(panel, label='Cipher', pos = (10,40), size=(-1,-1))
		self.Bind(wx.EVT_BUTTON,self.onSelect,self.cipherButton)

		# "Mesage"
		wx.StaticText(panel , label = "Message : " , pos = (12,12))

		# "Caesar shift: "
		wx.StaticText(panel, label = "Caesar shift: ", pos =(110,45))
		#input field
		messageInput = wx.TextCtrl(panel,value = "Enter a message", pos = (65,10), size= (250,-1))

		#cesar shift input
		self.shiftInput = wx.TextCtrl(panel,value= "3" , pos=(180,40),size = (15,-1))

		self.messageInput  = messageInput

                #append cipher modes
		lb.Append(CipherModes.CAESARc)
		lb.Append(CipherModes.CAESARd)
		lb.Append(CipherModes.REVERSEc)

		self.lb = lb

	#--------------------------------------------------------------------------------

	def onSelect(self,event):

		mode =  self.lb.GetStringSelection()
		text = self.messageInput.GetValue()

		if mode == CipherModes.CAESARc:

			#get shift value
			shift = int(self.shiftInput.GetValue())

			#get text to cipher
			cipher = self.cipherSys.caesarEncrypt(text,shift)

			#debug print
			print cipher

			#dialog box
			dlg = wx.MessageDialog(self,cipher,"Encrypted caesar",wx.OK | wx.ICON_INFORMATION)
			result = dlg.ShowModal()

		elif mode == CipherModes.CAESARd:

			#get shift value
			shift = int(self.shiftInput.GetValue())

			#get text to cipher
			cipher = self.cipherSys.caesarDecrypt(text,shift)

			#debug print
			print cipher

			#dialog box
			dlg = wx.MessageDialog(self,cipher,"Decrypted caesar",wx.OK | wx.ICON_INFORMATION)
			result = dlg.ShowModal()

		elif mode == CipherModes.REVERSEc:

			#get text to cipher
			cipher = self.cipherSys.reverseEncrypt(text)

			#debug print
			print cipher

			#dialog box
			dlg = wx.MessageDialog(self,cipher,"Reverse encryption",wx.OK | wx.ICON_INFORMATION)
			result = dlg.ShowModal()

############################################################################################################################################################

# a container class for constant strings of modes
class CipherModes():

	CAESARc= "Caesar Encryption"

	CAESARd = "Caesar Decryption"

	REVERSEc = "Reverse cipher"

############################################################################################################################################################

#Systems
class CipherSys():

	#--------------------------------------------------------------------------------

	def __init__(self):

		self.LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'

		self.ENCRYPT = 'encrypt'

		self.DECRYPT = 'decrypt'

	#encrypt (This exists to make the code easier to understand)
	def caesarEncrypt(self , message , key):

		return self.caesarCipher(message,key,self.ENCRYPT)

	#--------------------------------------------------------------------------------

	#decrypt (This exists to make the code easier to understand)
	def caesarDecrypt(self,message,key):

		return self.caesarCipher(message,key,self.DECRYPT)

	#--------------------------------------------------------------------------------

	#actual encryption and decryption method
	def caesarCipher(self,message,key,mode):

		msg = message.upper()

		# a variable to hold either the encrypted or decrypted message
		translated = ''

		for symbol in msg:
			if symbol in self.LETTERS:

				num = self.LETTERS.find(symbol)

				if mode == self.ENCRYPT:
					num = num + key
				elif mode == self.DECRYPT:
					num = num - key

				#handle additional wrap around
				if num >= len(self.LETTERS):
					num = num - len(self.LETTERS)
				elif num < 0:
					num = num + len(self.LETTERS)

				translated = translated + self.LETTERS[num]

			else:

				translated = translated + symbol

		return translated


	#--------------------------------------------------------------------------------

	def reverseCipher(self,message,mode):

		letters_maxIndex = len(self.LETTERS) - 1

		message = message.upper()

		translated = ''

		for symbol in message:

			if symbol in self.LETTERS:

				index = self.LETTERS.find(symbol)

				if mode == self.ENCRYPT:
					index = letters_maxIndex - index
				else:
					index = index- letters_maxIndex

				if index < 0:
					index = letters_maxIndex + index

				translated = translated + self.LETTERS[index]

			else:

				translated = translated + symbol

		return translated

	#--------------------------------------------------------------------------------

	#encrypt (This exists to enhance readability)
	def reverseEncrypt(self , message ):

		return self.reverseCipher(message,self.ENCRYPT)

	#--------------------------------------------------------------------------------

	#decrypt (This exists to enhance readability)
	def reverseDecrypt(self,message):

		return self.reverseCipher(message,self.DECRYPT)

	#--------------------------------------------------------------------------------





############################################################################################################################################################

#Run
if __name__ == '__main__':

	app = wx.App()
	frame = MainGui(parent = None, id = -1)
	frame.Show()
	app.MainLoop()













