#! /usr/bin/env python
#coding=utf-8
# GUI module generated by PAGE version 4.2.1
# In conjunction with Tcl version 8.6
#  Mar. 15, 2014 07:01:05 PM



import sys
import Archivo2
import Archivo3
import pygame



try:
  from Tkinter import *
except ImportError:
  from tkinter import *

try:
  import ttk
  
  ##
  # @brief Determina si la version de  Python es 3.X
  py3 = 0
except ImportError:
  import tkinter.ttk as ttk
  py3 = 1


#import Interfaz_support


##
# @brief Empieza el simulador como una aplicación principal.
#
# @return None
def vp_start_gui():
  global val, w, root
  root = Tk()
  root.title('CNC')
  root.geometry('314x316+159+189')
  w = CNC (root)
  #Interfaz_support.init(root, w)
  root.mainloop()
  pygame.quit()



##
# @brief Variable de la ventana creada
w = None



##
# @brief Crea la ventana del simulador en caso de ser un módulo en vez de ser una aplicación 
# principal
#
# @param root Elemento de control creado por el sistema TK
# @param param Elementos extras
#
# @return w_win Devuelve la ventana ya creada.
def create_CNC (root, param=None):
  global w, w_win, rt
  rt = root
  w = Toplevel (root)
  w.title('CNC')
  w.geometry('314x316+159+189')
  w_win = CNC (w)
  Interfaz_support.init(w, w_win, param)
  return w_win



##
# @brief Función que funciona como un destructor
#
# @return None
def destroy_CNC ():
  global w
  w.destroy()
  w = None


##
# @brief Clase que sirve para la pantalla de control de la simulación.
class CNC:

  ##
  # @brief Inicia la GUI
  #
  # @param master Indica que objeto funcionara como controlador del objeto creado por esta clase
  #
  # @return None
  def __init__(self, master=None):
    _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
    _fgcolor = '#000000'  # X11 color: 'black'
    _compcolor = '#d9d9d9' # X11 color: 'gray85'
    _ana1color = '#d9d9d9' # X11 color: 'gray85' 
    _ana2color = '#d9d9d9' # X11 color: 'gray85'

    
    ## @var posicion
    # @brief Guarda la posicion que tiene la simulación.
    #self.posicion=(0,0)


    ## @var master
    # @brief Variable que asigna el control del objeto creado
    self.master=master


    ## @var style
    # @brief Variable que asigna o controla el estilo de la ventana.
    self.style = ttk.Style()
   
    if sys.platform == "win32":
      self.style.theme_use('winnative')
    self.style.configure('.',background=_bgcolor)
    self.style.configure('.',foreground=_fgcolor)
    self.style.configure('.',font="TkDefaultFont")
    self.style.map('.',background=
      [('selected', _compcolor), ('active',_ana2color)])
    master.configure(highlightcolor="black")

    ## @var app
    # @brief Iniciando CNC, en este caso una simulación
    self.app=Archivo2.Muestra()
    
    ## @var Info
    # @brief Definiendo controles y etiquetas
    self.Info = ttk.Labelframe (master)
    self.Info.place(relx=0.02,rely=0.01,relheight=0.32,relwidth=0.96)
    self.Info.configure(text='''Posición''')
    self.Info.configure(width=300)

    
    ## @var InfoPX
    # @brief Etiqueda conteniendo el texto Posición X
    self.InfoPX = Label (self.Info)
    self.InfoPX.place(relx=0.03,rely=0.15,height=18,width=64)
    self.InfoPX.configure(activebackground="#f9f9f9")
    self.InfoPX.configure(text='''Posición X''')


    ## @var InfoPY
    # @brief Etiqueta conteninedo el texto Posición Y
    self.InfoPY = Label (self.Info)
    self.InfoPY.place(relx=0.03,rely=0.61,height=18,width=63)
    self.InfoPY.configure(activebackground="#f9f9f9")
    self.InfoPY.configure(text='''Posición Y''')


    ## @var PX
    # @brief Posición actual del eje X
    self.PX = Label (self.Info)
    self.PX.place(relx=0.27,rely=0.15,height=18,width=44)
    self.PX.configure(activebackground="#f9f9f9")
    self.PX.configure(justify=RIGHT)
    self.PX.configure(text='''0''')
    self.PX.configure(width=5)


    ## @var PY
    # @brief Posición actual del eje Y
    self.PY = Label (self.Info)
    self.PY.place(relx=0.27,rely=0.61,height=18,width=44)
    self.PY.configure(activebackground="#f9f9f9")
    self.PY.configure(justify=LEFT)
    self.PY.configure(text='''0''')
    self.PY.configure(width=5)


    ## @var NPX
    # @brief Permite establecer a que posición de X queremos ir
    self.NPX = Entry (self.Info)
    self.NPX.place(relx=0.5,rely=0.15,relheight=0.2,relwidth=0.21)
    self.NPX.configure(background="white")
    self.NPX.configure(foreground="black")
    self.NPX.configure(font="TkFixedFont")
    self.NPX.configure(selectbackground="#c4c4c4")
    self.NPX.configure(width=8)
    self.NPX.delete(0,END)
    self.NPX.insert(0,"0")
    self.NPX.configure(justify=LEFT)


    ## @var NPY
    # @brief Posición de Y a la que queremos ir
    self.NPY = Entry (self.Info)
    self.NPY.place(relx=0.5,rely=0.58,relheight=0.2,relwidth=0.21)
    self.NPY.configure(background="white")
    self.NPY.configure(foreground="black")
    self.NPY.configure(font="TkFixedFont")
    self.NPY.configure(selectbackground="#c4c4c4")
    self.NPY.configure(width=8)
    self.NPY.delete(0,END)
    self.NPY.insert(0,"0")
    self.NPY.configure(justify=LEFT)


    ## @var Ir_a
    # @brief Boton que llama la función de desplazamiento en la simulación.
    self.Ir_a = Button (self.Info,command=self.ir)
    self.Ir_a.place(relx=0.73,rely=0.1,height=26,width=60)
    self.Ir_a.configure(activebackground="#d9d9d9")
    self.Ir_a.configure(text='''Ir a:''')


    ## @var Marca_p
    # @brief Llama a la función de desplazamiento indicandole ademas que marque el punto a donde nos hemos desplazado. 
    self.Marca_p = Button (self.Info,command=self.marcar)
    self.Marca_p.place(relx=0.73,rely=0.55,height=26,width=60)
    self.Marca_p.configure(activebackground="#d9d9d9")
    self.Marca_p.configure(text='''Marca:''')


    ## @var Linea
    # @brief Definiendo los controles que controlan el dibjo de la línea y el cuadrado.
    self.Linea = ttk.Labelframe (master)
    self.Linea.place(relx=0.02,rely=0.33,relheight=0.32,relwidth=0.96)
    self.Linea.configure(text='''Dibujar línea o cuadrado''')
    self.Linea.configure(width=300)


    ## @var LPX
    # @brief Coordenada X donde comienza la línea o el cuadrado. 
    self.LPX = Entry (self.Linea)
    self.LPX.place(relx=0.27,rely=0.19,relheight=0.2,relwidth=0.21)
    self.LPX.configure(background="white")
    self.LPX.configure(foreground="black")
    self.LPX.configure(font="TkFixedFont")
    self.LPX.delete(0,END)
    self.LPX.insert(0,"270")
    self.LPX.configure(selectbackground="#c4c4c4")
    self.LPX.configure(width=8)


    ## @var LPY
    # @brief Coordenada Y donde comienza la línea o el cuadrado.
    self.LPY = Entry (self.Linea)
    self.LPY.place(relx=0.55,rely=0.19,relheight=0.2,relwidth=0.21)
    self.LPY.configure(background="white")
    self.LPY.configure(foreground="black")
    self.LPY.configure(font="TkFixedFont")
    self.LPY.delete(0,END)
    self.LPY.insert(0,"190")
    self.LPY.configure(selectbackground="#c4c4c4")
    self.LPY.configure(width=8)


    ## @var LPX1
    # @brief Coordenada X donde termina la línea o el cuadrado
    self.LPX1 = Entry (self.Linea)
    self.LPX1.place(relx=0.27,rely=0.55,relheight=0.2,relwidth=0.21)
    self.LPX1.configure(background="white")
    self.LPX1.configure(foreground="black")
    self.LPX1.configure(font="TkFixedFont")
    self.LPX1.delete(0,END)
    self.LPX1.insert(0,"370")
    self.LPX1.configure(selectbackground="#c4c4c4")
    self.LPX1.configure(width=8)


    ## @var LPY1
    # @brief Coordenada Y donde termina la línea o el cuadrado.
    self.LPY1 = Entry (self.Linea)
    self.LPY1.place(relx=0.55,rely=0.55,relheight=0.2,relwidth=0.21)
    self.LPY1.configure(background="white")
    self.LPY1.configure(foreground="black")
    self.LPY1.configure(font="TkFixedFont")
    self.LPY1.delete(0,END)
    self.LPY1.insert(0,"290")    
    self.LPY1.configure(selectbackground="#c4c4c4")
    self.LPY1.configure(width=8)


    ## @var LLX
    # @brief Etiqueta con el texto Inicio en X.
    self.LLX = Label (self.Linea)
    self.LLX.place(relx=0.03,rely=0.2,height=18,width=67)
    self.LLX.configure(activebackground="#f9f9f9")
    self.LLX.configure(text='''Inicio en X''')


    ## @var LLX1
    # @brief Etiqueta con el texto Fin en X.
    self.LLX1 = Label (self.Linea)
    self.LLX1.place(relx=0.03,rely=0.57,height=18,width=53)
    self.LLX1.configure(activebackground="#f9f9f9")
    self.LLX1.configure(text='''Fin en X''')

    ## @var LLY
    # @brief Etiqueta con el texto Y.
    self.LLY = Label (self.Linea)
    self.LLY.place(relx=0.5,rely=0.2,height=18,width=11)
    self.LLY.configure(activebackground="#f9f9f9")
    self.LLY.configure(text='''Y''')

    ## @var LLY1
    # @brief Etiqueta con el texto Y.
    self.LLY1 = Label (self.Linea)
    self.LLY1.place(relx=0.5,rely=0.57,height=18,width=11)
    self.LLY1.configure(activebackground="#f9f9f9")
    self.LLY1.configure(text='''Y''')


    ## @var DLinea
    # @brief Manda a llamar la función que dibuja una línea.
    self.DLinea = Button (self.Linea,command=self.linea)
    self.DLinea.place(relx=0.77,rely=0.15,height=26,width=58)
    self.DLinea.configure(activebackground="#d9d9d9")
    self.DLinea.configure(text='''Línea''')
    

    ## @var DCuadrado
    # @brief Llama a la función que dibuja un cuadro.
    self.DCuadrado = Button (self.Linea,command=self.cuadro)
    self.DCuadrado.place(relx=0.77,rely=0.53,height=26,width=58)
    self.DCuadrado.configure(activebackground="#d9d9d9")
    self.DCuadrado.configure(text='''Cuadro''')


    ## @var Circulo
    # @brief Controles del círculo.
    self.Circulo = ttk.Labelframe (master)
    self.Circulo.place(relx=0.02,rely=0.65,relheight=0.32,relwidth=0.96)
    self.Circulo.configure(text='''Dibujar círculo''')
    self.Circulo.configure(width=300)


    ## @var CCX
    # @brief Etiqueta con el texto Centro en X.
    self.CCX = Label (self.Circulo)
    self.CCX.place(relx=0.02,rely=0.21,height=18,width=75)
    self.CCX.configure(activebackground="#f9f9f9")
    self.CCX.configure(text='''Centro en X''')


    ## @var CX
    # @brief Coordenada X del centro del círculo.
    self.CX = Entry (self.Circulo)
    self.CX.place(relx=0.28,rely=0.21,relheight=0.2,relwidth=0.21)
    self.CX.configure(background="white")
    self.CX.configure(foreground="black")
    self.CX.configure(font="TkFixedFont")
    self.CX.delete(0,END)
    self.CX.insert(0,"320")
    self.CX.configure(selectbackground="#c4c4c4")
    self.CX.configure(width=8)


    ## @var CCY
    # @brief Etiqueta con el texto Y.
    self.CCY = Label (self.Circulo)
    self.CCY.place(relx=0.5,rely=0.21,height=18,width=11)
    self.CCY.configure(activebackground="#f9f9f9")
    self.CCY.configure(text='''Y''')


    ## @var CY
    # @brief Coordenada Y del centro del círculo.
    self.CY = Entry (self.Circulo)
    self.CY.place(relx=0.55,rely=0.21,relheight=0.2,relwidth=0.21)
    self.CY.configure(background="white")
    self.CY.configure(foreground="black")
    self.CY.configure(font="TkFixedFont")
    self.CY.delete(0,END)
    self.CY.insert(0,"240")
    self.CY.configure(selectbackground="#c4c4c4")
    self.CY.configure(width=8)


    ## @var CCR
    # @brief Etiqueta con el texto Radio.
    self.CCR = Label (self.Circulo)
    self.CCR.place(relx=0.03,rely=0.56,height=18,width=37)
    self.CCR.configure(activebackground="#f9f9f9")
    self.CCR.configure(text='''Radio''')


    ## @var CR
    # @brief Longitud del radio del círculo.
    self.CR = Entry (self.Circulo)
    self.CR.place(relx=0.28,rely=0.57,relheight=0.2,relwidth=0.21)
    self.CR.configure(background="white")
    self.CR.configure(foreground="black")
    self.CR.configure(font="TkFixedFont")
    self.CR.delete(0,END)
    self.CR.insert(0,"50")
    self.CR.configure(selectbackground="#c4c4c4")
    self.CR.configure(width=8)


    ## @var DCirc
    # @brief Manda llamar a la función que dibuja el círculo.
    self.DCirc = Button (self.Circulo,command=self.circulo)
    self.DCirc.place(relx=0.73,rely=0.46,height=26,width=67)
    self.DCirc.configure(activebackground="#d9d9d9")
    self.DCirc.configure(text='''Círculo''')


  ##
  # @brief Posiciona la simulación en un punto. 
  # Determina si un punto esta dentro de las coordenadas de la simulación, si es asi mueve la simulación hasta dicho punto.
  # @return None
  
  def ir(self):
    
    try:
      
      posicion=(int(self.NPX.get()),int(self.NPY.get()))
    except ValueError:
      print("Error")
      return None
    
    if 0>posicion[0]>=640|0>posicion[1]>=480: return None
       
    print("Ir a: "+str(posicion))
    
    self.master.withdraw()
    self.app.mueve(posicion)
    
    self.master.deiconify()
    self.posicion=self.app.coordenada
    self.app.dibujar()
    self.actualizar()


  ##
  # @brief Marca un punto.
  # Marca un punto dado, siempre que este dentro del rango de la simulación.
  # @return None
  
  def marcar(self):
    
    try:
      
      posicion=(int(self.NPX.get()),int(self.NPY.get()))
    except ValueError:
      print("Error")
      return None
    
    if 0>posicion[0]>=640|0>posicion[1]>=480: return None
    
    print("Marcar punto: "+str(posicion))
    self.master.withdraw()
    self.app.mueve(posicion,True)
    self.master.deiconify()
    self.posicion=self.app.coordenada
    self.app.dibujar()
    self.actualizar()


  ##
  # @brief Dibuja una línea.
  #
  # Dibuja una línea cuando los puntos inicial y final estan en el área de la simulación.
  # @return None
  def linea(self):
    # """ Dibuja una linea """
    try:
      # """ Intenta obtener los puntos finales de la línea """
      posicion0=(int(self.LPX.get()),int(self.LPY.get()))
      posicion1=(int(self.LPX1.get()),int(self.LPY1.get()))
    except ValueError:
      print("Error")
      return None
    # """ Determina si los puntos de la línea son válidos """
    if 0>posicion0[0]>=640|0>posicion0[1]>=480|0>posicion1[0]>=640|0>posicion1[1]>=480|posicion0==posicion1: return None
    # """ Dibuja la línea """
    print("Linea de:"+str(posicion0)+" a:"+str(posicion1))
    self.master.withdraw()
    linea=Archivo3.get_line(posicion0[0],posicion0[1],posicion1[0],posicion1[1])
    for p in linea:
      self.app.mueve(p,True)
    self.master.deiconify()
    self.app.dibujar()
    self.actualizar()


  ##
  # @brief Dibuja un cuadro.
  #
  # Diguja un cuadro dibujado mediante cuatro lineas, determinado solo por dos puntos. Los puntos deben estar dentro del área de simulación para poder dibujarse.
  # @return None
  def cuadro(self):
    #""" Diuja un cuadro """
    try:
      #""" Intenta obtener los puntos finales del cuadro """
      posicion0=(int(self.LPX.get()),int(self.LPY.get()))
      posicion1=(int(self.LPX1.get()),int(self.LPY1.get()))
    except ValueError:
      print("Error")
      return None
    #""" Determina si los puntos del cuadro son válidos """
    if 0>posicion0[0]>=640|0>posicion0[1]>=480|0>posicion1[0]>=640|0>posicion1[1]>=480|posicion0==posicion1: return None
    print("Cuadro de:"+str(posicion0)+" a:"+str(posicion1))
    self.master.withdraw()
    linea=Archivo3.get_line(posicion0[0],posicion0[1],posicion1[0],posicion0[1])
    for p in linea:
      self.app.mueve(p,True)
    linea=Archivo3.get_line(posicion1[0],posicion0[1],posicion1[0],posicion1[1])
    for p in linea:
      self.app.mueve(p,True)
    linea=Archivo3.get_line(posicion1[0],posicion1[1],posicion0[0],posicion1[1])
    for p in linea:
      self.app.mueve(p,True)
    linea=Archivo3.get_line(posicion0[0],posicion1[1],posicion0[0],posicion0[1])
    for p in linea:
      self.app.mueve(p,True)
    self.master.deiconify()
    self.app.dibujar()
    self.actualizar()


  ##
  # @brief Dibuja un círculo
  #
  # Simula o dibuja un círculo dentro del área de simulación, tanto las corrdenadas del centro, comola circunferencia del círculo deben estar dentro del área permitida.
  #
  # @return None
  def circulo(self):
    #""" Dibuja un círculo """
    try:
      #""" Intenta obtener los puntos finales del cuadro """
      centro=(int(self.CX.get()),int(self.CY.get()))
      radio=int(self.CR.get())     
    except ValueError:
      print("Error")
      return None
    if 0>centro[0]<=640|0>centro[1]>=480|0>radio>=(640/2)|centro[0]+radio>=640|centro[0]-radio<0|centro[1]+radio>=480|centro[1]-radio>0: return None
    self.master.withdraw()
    circulo=Archivo3.circle(radio,centro)
    print("Círculo de radio: "+str(radio)+" con centro en: "+str(centro))
    for p in circulo:
      self.app.mueve(p,True)
    self.master.deiconify()
    self.app.dibujar()
    self.actualizar()
  
  ##
  # @brief Actualiza la posición.
  #
  # Despliega en la GUI la información de donde se encuentra actualmente la simulación.
  #
  # @return None
  def actualizar(self):
    self.PX["text"]=str(self.app.coordenada[0])
    self.PY["text"]=str(self.app.coordenada[1])


  ##
  # @brief Destructor del objeto creado con esta clase.
  #
  # @return None
  def destroy(self):
    del(self.app)
    self.destroy(self.app)
    self.destroy()


if __name__ == '__main__':
  vp_start_gui()
