from Tkinter import *
from numpy import *
from math import *
import pickle


# defino variables globales
w_max=500.0	# ancho de ventana
h_max=500.0	# alto de ventana
w_min=0.0
h_min=0.0
x_min=-100.0	# rango de las xdefdef
x_max=100.0
y_min=-100.0	#rango de las y
y_max=100.0
num_lados=0
h_protu=0.0
pi=3.1415927
pant_x=[]	# lista donde guardo las coordenadas x de los puntos en unidades de pantalla
pant_y=[]	# lista donde guardo las coordenadas y de los puntos en unidades de pantalla

geo_x=[]	# lista donde guardo las coordenadas x de los puntos en unidades de geometria
geo_y=[]	# lista donde guardo las coordenadas y de los puntos en unidades de geometria
geo_z=[]	# lista donde guardo las coordenadas z de los puntos en unidades de geometria

# transforma la coorde x del mouse 
# al dominio w_min w_max (eje horizontal)
# al poner por ejemplo x_min=x_min estoy usando variable global para pasar
# como argumento
def coord_x(w,x_min=x_min,x_max=x_max,w_min=w_min,w_max=w_max):
	if w < w_max:
		d =int(-1*( (w_max-w)/(w_max-w_min) *(x_max-x_min)+x_min))
		#print d
		return d
	else:
		return -1

# transforma y del dominio y_min y_max
# al dominio h_min h_max
def coord_y(w,y_min=y_min,y_max=y_max,h_min=h_min,h_max=h_max):
	if w < h_max:
		d =int((h_max-w)/(h_max-h_min)*(y_max-y_min)+y_min)
		#print d
		return d
	else:
		return -1

def coordenadas(event):
	a=[]
	w.textx=Label(w,text=coord_x(event.x))
	w.textx.grid(row=1, column=1)
	a.append(coord_x(event.x))
	w.textx=Label(w,text=coord_y(event.y))
	w.textx.grid(row=1, column=2)
	a.append(coord_y(event.y))
	#print "clicked at", event.x, event.y
	return a

def dibuja_linea(pant_x,pant_y):
	largo=len(pant_x)-1
	print " largo", len(pant_x)
	if len(pant_x)>1:
		print pant_x,pant_y
		b.create_line(pant_x[largo],pant_y[largo],pant_x[largo-1],pant_y[largo-1],fill="black",width=1)
	return

def dibuja_poli():
	global pant_x
	global pant_y
	largo=len(pant_x)
	print " largo", len(pant_x)
	if len(pant_x)>1:
		for i in range(largo):
			print pant_x,pant_y
			print geo_x,geo_y
			b.create_line(pant_x[i],pant_y[i],pant_x[i-1],pant_y[i-1],fill="blue",width=1)
	return


def graba_file():
	global geo_x
	global geo_y
	global h_protu

	cant_vert_base=len(geo_x)	#cantidad de vertices del poligono base
	cant_caras=cant_vert_base+2
	cant_bordes=cant_vert_base*3


	#lleno con ceros los z que me faltan de la TAPA
	for i in range(cant_vert_base):
		geo_z.append(h_protu)

	#copio las coordenadas de x  e y en la cara TAPA
	geo_x.extend(geo_x)
	geo_y.extend(geo_y)

	cant_vert_totales=len(geo_x)
	
	vert=zeros([cant_vert_totales,4],float)	# defino una matriz para guardar las coordenadas de los puntos
	e=zeros([cant_bordes,8], int)	#defino la matriz para guardar la topologia


	print " cant vertices base", cant_vert_base
	print " cant vertices totales", cant_vert_totales	
	if len(geo_x)>1:
		#lleno la matriz de vertices
		for i in range(cant_vert_totales):
			vert[i][0]=geo_x[i]
			vert[i][1]=geo_y[i]
			vert[i][2]=geo_z[i]
			vert[i][3]=1.0
		print vert		
		#lleno la matriz e de topologia
		# vertice de inicio para todos
		for i in range(cant_bordes):
			if i<cant_vert_totales:
				e[i][0]=i
			else:
				e[i][0]=i-cant_vert_totales
				#vertice de fin para los laterales
				e[i][1]=i-cant_vert_base
		#vertice de fin para la base
		for i in range(cant_vert_base-1):
			if i<cant_vert_base:
				e[i][1]=i+1
			else:
				e[i][1]=0
		#vertice de fin para la tapa
		for i in range(cant_vert_base,cant_vert_totales):
			print "....",i
			if i<cant_vert_totales-1:
				e[i][1]=i+1
			else:
				e[i][1]=cant_vert_base

		#ahora lleno las caras de derecha e izquierda para la base
		for i in range(cant_vert_base):
			if i<cant_vert_base:
				e[i][2]=i+2
				e[i][3]=0
		#ahora lleno las caras de derecha e izquierda para la tapa
		for i in range(cant_vert_base,cant_vert_totales):
			e[i][2]=1
			e[i][3]=i-cant_vert_base+2
		#ahora lleno las caras de derecha e izquierda para laterales
		for i in range(cant_vert_totales,cant_bordes):
			if i==cant_vert_totales:
				e[i][2]=cant_vert_base+1
			else:
				e[i][2]=i-cant_vert_totales+1
			e[i][3]=i-cant_vert_totales+2
		#ahora lleno los bordes anteriores y posteriores
		for i in range(cant_bordes):
			for j in range(cant_bordes):
				if i<>j:
					if e[i][0]==e[j][0]:
						if e[i][2]==e[j][3]:
							e[i][5]=j
						if e[i][3]==e[j][2]:
							e[i][6]=j

					if e[i][1]==e[j][1]:
						if e[i][2]==e[j][3]:
							e[i][4]=j
						if e[i][3]==e[j][2]:
							e[i][7]=j

					if e[i][0]==e[j][1]:
						if e[i][2]==e[j][2]:
							e[i][5]=j
						if e[i][3]==e[j][3]:
							e[i][6]=j
						
					if e[i][1]==e[j][0]:
						if e[i][2]==e[j][2]:
							e[i][4]=j
						if e[i][3]==e[j][3]:
							e[i][7]=j
							
									
				


		print e
			#print " [vert]",i,"x:",geo_x[i],"y:",geo_y[i],"z:",geo_z[i]

		#lleno la matriz de caras con el numero de un borde perteneciente a ella
		# los subindices los subindices 1 a 3  para los vertices para calcular perpendicular
		# el 4 queda vacio
 	        # del 5 al 7 iran las componentes del vector perpendicular que pondra el caras*
		f=zeros([cant_caras,8], int)
			
		f[0]=0
		f[1]=cant_vert_base
		dum=2*cant_vert_base
		for i in range(2,cant_caras):
			
			f[i]=dum
			dum=dum+1
			#print "cara",i-2,f[i-2]
		print f

		archivo = open("mouse_e.txt", "w")
		pickle.dump(e,archivo)
		archivo.close()
		archivo = open("mouse_v.txt", "w")
		pickle.dump(vert,archivo)
		archivo.close()
		archivo = open("mouse_f.txt", "w")
		pickle.dump(f,archivo)
		archivo.close()
	return


def pone_punto(event):
	global pant_x
	global geo_x
	global pant_y
	global geo_y
	a=[]
	
	pant_x.append(event.x)
	pant_y.append(event.y)
	a.append(coord_x(event.x))
	a.append(coord_y(event.y))
	geo_x.append(coord_x(event.x))
	geo_y.append(coord_y(event.y))
	geo_z.append(0.0)
		
	print "clicked at", event.x, event.y,a
	dibuja_linea(pant_x,pant_y)
	return a

def circulo(event):
	global pant_x
	global geo_x
	global pant_y
	global geo_y
	global num_lados
	a=[]
	num_lados=int(w.num_la.get())
	if num_lados<3:
		num_lados=3
	#num_lados=20
	#radio=50
	radio=int(w.rad.get())
	centro_x=event.x
	centro_y=event.y
	for i in range(1,num_lados+1):
		pant_x.append(radio*cos(2*pi/num_lados*i)+centro_x)
		pant_y.append(radio*sin(2*pi/num_lados*i)+centro_y)
		#a.append(coord_x(40.0*cos(2*pi/i)))
		#a.append(coord_y(40.0*sin(2*pi/i)))
		geo_x.append(coord_x(radio*cos(2*pi/num_lados*i)+centro_x))
		geo_y.append(coord_y(radio*sin(2*pi/num_lados*i)+centro_y))
		geo_z.append(0.0)
	dibuja_poli()
	return


def altura(x):
	global h_protu
	h_protu = float(x)
	
	return
	
w = Tk()
b = Canvas(w, height=h_max, width=w_max, background="white")
b.grid(row=0,column=0,columnspan=3) #pack()
b.create_line(w_max/2,0,w_max/2,h_max,fill="red",width=1)
b.create_line(0,h_max/2,w_max,h_max/2,fill="red",width=1)

b.bind("<Motion>", coordenadas)
b.bind("<Button-1>",pone_punto)
b.bind("<Button-3>",circulo)

w.button = Button(w, text="QUIT", fg="red", command=w.quit)
w.button.grid(row=1,column=0)

w.button = Button(w, text="POLI", fg="black", command=dibuja_poli)
w.button.grid(row=2,column=1)

w.button = Button(w, text="SAVE", fg="black", command=graba_file)
w.button.grid(row=2,column=2)

w.s=Scale(w,orient="horizontal",command=altura,from_=0.0,to=100.0,resolution=5.0)
w.s.grid(row=2,column=0)

w.num_la=Entry(w,width=10)
w.lab1=Label(w,text="Lados")
w.lab1.grid(row=3,column=0)
w.num_la.grid(row=4,column=0)

w.rad=Entry(w,width=10)
w.lab2=Label(w,text="Radio")
w.lab2.grid(row=3,column=1)
w.rad.grid(row=4,column=1)



print " num lados", num_lados


w.mainloop()
		
