'''
Created on May 31, 2011

@author: svenkratz
'''
from Tkinter import *

import matplotlib
matplotlib.use('TkAgg')

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import numpy as np

import math


class TKMatplotlibImage:
	'''Diese Klasse bettet ein Matplotlib-Plot in einem TkInter-Widget ein'''
	def __init__(self, master, image):
		self.master = master
		self.image = image
		self.figure = Figure(figsize=(4,5), dpi=100)
		self.plot =  self.figure.add_subplot(111)
		plt.gray()
		self.plot.imshow(self.image)
		self.canvas = FigureCanvasTkAgg(self.figure, master=master)
		self.canvas.show()
		self.canvas.get_tk_widget().pack()
	
	def replot(self, normalize = False):
		'''Plot neu zeichnen'''
		print "Replot! Norm=",normalize
		self.plot.clear()
		if normalize:
			self.plot.imshow(self.image)
		else:
			self.plot.imshow(self.image, norm = matplotlib.colors.NoNorm())
		self.canvas.show()
		self.canvas.get_tk_widget().pack()




class ConvolveDialog:
	'''Zeigt einen Dialog an, ueber den eine Kernel-Matrix eingegeben werden kann'''
	def __init__(self, master, input_window, output_window, k_size=3):
		
		self.entries = []
		# Textfelder in Matrixform verteilen
		for i in range(k_size):
			row = []
			for j in range(k_size):
				print "Entry",i,j
				entry = Entry(master=master, width=4)
				if i == k_size / 2 and j == k_size / 2:
					entry.insert(0,1.0)
				else:
					entry.insert(0,0.0)
				entry.grid(row=i,column=j)
				row.append(entry)
				
			self.entries.append(row)
		
		
		self.norm_checked = IntVar(0)
		self.norm_checkButton = Checkbutton(master, text="normalize output", variable = self.norm_checked)
		self.norm_checkButton.select()
		self.norm_checkButton.grid(row=k_size, columnspan=k_size)
		
		# Button, mit dem die Konvolution aufgerufen wird, Ruft bei Click self.command auf
		self.button = Button(master, text="Convolve", command=self.command)
		self.button.grid(row=k_size+1, columnspan=k_size)
		
		self.input_window = input_window
		self.output_window = output_window
		
		self.conv_matrix= None
		
		self.getConvMatrix()
		print "Matrix", self.conv_matrix
		self.command()
		

		
	def command(self):
		##### Hier kann was mit dem Ausgabebild gemacht werden
		
		# holt die aktuelle Matrix des Kernes
		self.getConvMatrix()
		print "Starting convolution"
		# Konvolution des Eingabebildes
		convolved_image = self.convolve(self.input_window.image, self.conv_matrix)
		self.output_window.image = convolved_image
		
		####
		# Neuzeichnen des Ausgabeplots
		###
		normalize = self.norm_checked.get()
		output_window.replot(normalize)


	
	def getConvMatrix(self):
		#matrix = np.zeros((k_size,k_size))
		entries = [[float(e.get()) for e in row] for row in self.entries]
		# transponieren, da Eintraege 90 Grad gedreht sind
		self.conv_matrix = np.array(entries).transpose()
		print self.conv_matrix
	
		
	def convolve(self, image, matrix):
		#####################################
		#
		#  Hier Konvolution Implementieren!! 
		#
		#####################################
		output = image # dummy code, ersetzen!
		return output
	
	
	
	
# Root-Fenster
root = Tk()
ente = plt.imread('ente.png')
output = np.zeros(ente.shape)
# Neues Toplevel-Fenster fuer das Eingabebild
input_top = Toplevel(root)
input_top.title("Input Image")
# Neues Toplevel-Fenster fuer das Ausgabebild
output_top = Toplevel(root)
output_top.title("Output Image")
root.title("Convolution Matrix")


input_window = TKMatplotlibImage(input_top, ente)
output_window = TKMatplotlibImage(output_top, output)

# Dialog fuer die Eingabe einer Konvolutionsmatrix
convolve_dialog = ConvolveDialog(root, input_window, output_window)

# Geometry verschiebt die einzelnen Fenster
# muss ggf. je nach Bildschirmaufloesung angepasst werden
input_top.geometry('800x600+50+50')
output_top.geometry('800x600+950+50')
root.geometry('200x200+850+50')
root.deiconify()
root.mainloop()