#!/usr/bin/env python
# -*- coding: ascii -*-
from __future__ import print_function

# NOTICE... this file is generated by TkGridGUI.
# Any code or comments added by the user must be in designated areas ONLY.
# User additions will be lost if they are placed in code-generated areas.
# (i.e. Saving from TkGridGUI will over-write code-generated areas.)

# TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "imports"


from __future__ import unicode_literals
from future import standard_library
standard_library.install_aliases()
from builtins import str
from builtins import range
from builtins import object

from tkinter.ttk import Combobox, Progressbar, Separator, Treeview, Notebook

from tkinter import *
from tkinter import Button, Canvas, Checkbutton, Entry, Frame, Label, LabelFrame
from tkinter import Listbox, Message, Radiobutton, Spinbox, Text
from tkinter import OptionMenu
import tkinter.filedialog
from tkinter import _setit as set_command


# >>>>>>insert any user code below this comment for section "imports"
text_warn = 'WARNING:\n\nselecting OK\nwill REPLACE\ncurrent points\nwith\ngenerated\npoints'
text_info = 'NOTE:\nselecting OK\n\nwill ADD\ngenerated\npoints\nto\ncurrent\npoints'

# Place any user import statements here
from copy import deepcopy
import os, sys, zipfile, json
try:
    from StringIO import StringIO as MemoryIO
except:
    from io import BytesIO as MemoryIO
    
from PIL import Image, ImageDraw, ImageTk
from PIL import ImageFilter
from PIL.ImageFilter import GaussianBlur

import numpy as np
from digiplot.InterpProp_scipy import InterpProp
from scipy.ndimage import gaussian_filter1d

from digiplot.plot_area import PlotArea

# TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "top_of_init"

if sys.version_info < (3,):
    from tkSimpleDialog import Dialog
else:
    from tkinter.simpledialog import Dialog

class _Dialog(Dialog):
    # use dialogOptions dictionary to set any values in the dialog
    def __init__(self, parent, title = None, dialogOptions=None):
    
        self.dialogOptions = dialogOptions
        Dialog.__init__(self, parent, title)

class _auto_detect(_Dialog):

    def body(self, master):
        dialogframe = Frame(master, width=741, height=560)
        self.dialogframe = dialogframe
        dialogframe.pack()


        self.make_Canvas_1( self.dialogframe )         #      Canvas:  at Main(2,2)
        self.make_Frame_1( self.dialogframe )          #       Frame:  at Main(2,1)
        self.make_Button_1( self.Frame_1 )             #      Button: Generate Points : at Frame_1(8,1)
        self.make_Checkbutton_1( self.Frame_1 )        # Checkbutton: Replace or Add : at Frame_1(10,1)
        self.make_Checkbutton_2( self.Frame_1 )        # Checkbutton: Show Blur : at Frame_1(9,1)
        self.make_Entry_1( self.Frame_1 )              #       Entry: 0.02 : at Frame_1(5,1)
        self.make_Label_1( self.Frame_1 )              #       Label: Blur Radius : at Frame_1(0,1)
        self.make_Label_2( self.Frame_1 )              #       Label: #Generated Points : at Frame_1(2,1)
        self.make_Label_3( self.Frame_1 )              #       Label: Explore Fraction : at Frame_1(4,1)
        self.make_Label_4( self.Frame_1 )              #       Label: Masking Line Width : at Frame_1(6,1)
        self.make_Label_5( self.Frame_1 )              #       Label: Point Opacity : at Frame_1(11,1)
        self.make_Spinbox_1( self.Frame_1 )            #     Spinbox: Blur Radius : at Frame_1(1,1)
        self.make_Spinbox_2( self.Frame_1 )            #     Spinbox: 3 to 1000 : at Frame_1(3,1)
        self.make_Spinbox_3( self.Frame_1 )            #     Spinbox: 1 to 9 : at Frame_1(7,1)
        self.make_Spinbox_4( self.Frame_1 )            #     Spinbox: 1 to 255 : at Frame_1(12,1)
        self.make_Text_1( self.Frame_1 )               #        Text:  at Frame_1(13,1)

        self.dialogframe.rowconfigure(2, weight=1)
        self.dialogframe.rowconfigure(13, weight=1)
        self.dialogframe.columnconfigure(2, weight=1)

        # >>>>>>insert any user code below this comment for section "top_of_init"
        self.x, self.y, self.w, self.h = -1,-1,-1,-1
        self.dw_canv = -1
        self.dh_canv = -1
        self.need_resize = False
        
        self.d_frac = 0.02 # explore fraction normal to 1st curve estimate
        self.blur_radius = 3 # GaussianBlur radius
        self.num_points = 12 # number of point intervals to generate
        self.masking_line_size = 9 # used in (Will be kept odd)
        self.opacity = 155 # for points on drawing
        self.calc_pointL = [] # list of calculated points

        
        # bind master to <Configure> in order to handle any resizing, etc.
        # postpone self.dialog_master.bind("<Configure>", self.Master_Configure)
        self.initComplete = 0
        self.dialog_master = master
        self.dialog_master.bind('<Enter>', self.bindConfigure)
        
        # Mouse Wheel for Zooming in and out
        self.Canvas_1.bind("<MouseWheel>",self.MouseWheelHandler) # Windows Binding
        self.Canvas_1.bind("<Button-4>",self.MouseWheelHandler) # Linux Binding
        self.Canvas_1.bind("<Button-5>",self.MouseWheelHandler) # Linux Binding  
        
        self.is_dragging = False
        self.last_right_click_pos = (0,0) # any action calling Canvas_Find_Closest will set

        self.last_hover_pos = (0,0)
        self.in_canvas = False
        
        self.Canvas_1.bind("<Button-3>", self.Canvas_Begin_End_Drag)
        self.Canvas_1.bind("<B3-Motion>", self.Canvas_Drag_Axes)
        self.Canvas_1.bind("<Motion>", self.Canvas_Hover)
        self.Canvas_1.bind("<Enter>", self.Canvas_Enter)
        self.Canvas_1.bind("<Leave>", self.Canvas_Leave)
                
        self.resizable(1,1) # Linux may not respect this
        self.Canvas_1.focus_set()
        
        self.PA = deepcopy( self.dialogOptions['PA'] )
        self.PA_img = self.PA.img
        self.pointL = deepcopy( self.dialogOptions['pointL'] )
        
        self.fill_canvas()

    def fill_canvas(self):
        
        try:
            self.Canvas_1.delete("all")
        except:
            pass
        
        self.build_PA_img()
        
        self.photo_image = self.PA.get_tk_photoimage(greyscale=False, text='')
        
        self.Canvas_1.create_image(0,0, anchor=NW, image=self.photo_image )

    def build_PA_img(self):
        
        self.calc_pointL = [] # start with empty list of calculated points
        
        gray = self.PA_img.convert("L")
        w,h = self.PA_img.size
        
        rgb = Image.new('RGB', (w,h), (0,0,0))
        show_gray = Image.new('L', (w,h), 255)
        gray_mask = Image.new('L', (w,h), 0)
        rgb_mask = Image.new('L', (w,h), 0)
        
        draw_rgb = ImageDraw.Draw( rgb )
        draw_gray_mask = ImageDraw.Draw( gray_mask )
        draw_rgb_mask = ImageDraw.Draw( rgb_mask )
                
        pLL = [(P.x,P.y,P.fi,P.fj) for P in self.pointL]
        pLL.sort() # make sure increasing x
        
        fiL = []
        fjL = []
        fsL = [0.0] # approximate length along curve
        for i,pL in enumerate(pLL):
            #print(pL)
            x,y,fi,fj = pL
            fiL.append( fi )
            fjL.append( fj )
            if i>0:
                s = fsL[-1] +  ((fi-fiL[-2])**2 + (fj-fjL[-2])**2)**0.5
                fsL.append( s )
        #print( 'fsL=',fsL )
        s_total = fsL[-1]        
        
        # build interplators along 1st estimate of curve
        fjterp = InterpProp( fiL, fjL, extrapOK=True )
        fi_sterp = InterpProp( fsL, fiL, extrapOK=True )
            
            
        # draw approximate-interpolated curve
        ijL = [] # list of (i,j) for draw.line
        for i in range(101):
            s = i*s_total / 100.0
            fi = fi_sterp( s )
            
            fj = fjterp( fi )
            ijL.append( (int( w * fi ), int( h * fj )) )

        #draw_rgb.line( ijL, width=3, fill='red' )
        #draw_rgb_mask.line( ijL, width=3, fill=self.opacity )
        
        # try to eliminate line imperfections (holes in wide lines.)
        for i in [-1,0,1]:
            for j in [-1,0,1]:
                ij_newL = [(i+ii,j+jj) for ii,jj in ijL]
                draw_gray_mask.line( ij_newL, width=self.masking_line_size, fill=255 )
        
        
        # show data points
        for (x,y,fi,fj) in pLL:
            f_ipos = w * fi
            i = int( f_ipos )
            f_jpos = h * fj
            j = int( f_jpos )
            draw_rgb.rectangle(((i-4,j-4),(i+4,j+4)), fill ="blue", outline ="cyan") 
            draw_rgb_mask.rectangle(((i-4,j-4),(i+4,j+4)), fill=self.opacity, outline =self.opacity) 

        # show normal
        aspect = float(w) / float(h)
        #print('aspect=',aspect)
        
        show_gray.paste( gray, mask=gray_mask )
        show_gray = show_gray.filter( ImageFilter.GaussianBlur(radius=self.blur_radius ) ) 
        
        d = self.d_frac
        Npts = self.num_points
        for i in range(Npts + 1):
            s = i*s_total / float(Npts)
            fi = fi_sterp( s )
            fj = fjterp( fi )
            slope = -fjterp.deriv( fi ) # negative since fj=0 is at top
            #print(fi, fj, slope)
            try:
                normal = -1.0 / slope
            except:
                normal = 100.0 # any non-overflow big number should do.
            
            dfj = normal * d 
            dfi = d / aspect
            mult = d / ( dfj**2 + dfi**2 )**0.5
            dfj *= mult
            dfi *= mult
            
            fi_1 = fi - dfi
            fi_2 = fi + dfi
            
            fj_1 = fj + dfj
            fj_2 = fj - dfj
            
            i1 = int( fi_1 * w)
            j1 = int( fj_1 * h)
            
            i2 = int( fi_2 * w)
            j2 = int( fj_2 * h)
            
            draw_rgb.line( ((i1,j1),(i2,j2)), width=3, fill='magenta' )
            draw_rgb_mask.line( ((i1,j1),(i2,j2)), width=3, fill=self.opacity )
            #draw_rgb.rectangle(((i1-4,j1-4),(i1+4,j1+4)), fill ="blue", outline ="cyan") 
            
            # get 1D color array for edge-finding. (FROM show_gray)
            def get_ave_color( fi, fj ):
                i1 = int(  fi * w )
                j1 = int(  fj * h )
                c11 = show_gray.getpixel( (i1,j1) )
                return c11
            
            oneDL = []
            fi_oneDL = []
            fj_oneDL = []
            Nsteps = 100
            for n in range(Nsteps+1):
                fi = fi_1 + n*dfi*2 / Nsteps
                fj = fj_1 - n*dfj*2 / Nsteps
                oneDL.append( get_ave_color( fi, fj ) )
                fi_oneDL.append( fi )
                fj_oneDL.append( fj )
            gfilt_oneDL = gaussian_filter1d( oneDL, Nsteps/30.0 )
            
            # take the darkest points to find approximate center of line
            max_v = gfilt_oneDL.max()
            min_v = gfilt_oneDL.min()
            r = max_v - min_v
            cutoff = min_v + (max_v - min_v)*0.1
            minL = np.where(gfilt_oneDL <= cutoff )[0]
            #print( 'minL =', minL )
            
            # clamp iave into range of 0 to len(fi_oneDL)-1
            #iave = min( len(fi_oneDL)-1, max(0,np.argmin( gfilt_oneDL )))
            iave = int( sum(minL) / len(minL) )
            iave = min( len(fi_oneDL)-1, max(0,iave))
            
            fi = fi_oneDL[ iave ]
            fj = fj_oneDL[ iave ]
                        
            # use get_xy_at_fifj(self, fi, fj) in Digiplot code
            #x = self.PA.x_origin + (self.PA.xmax-self.PA.x_origin)*(fi-self.PA.fi_origin)/(self.PA.fimax-self.PA.fi_origin)
            #y = self.PA.y_origin + (self.PA.ymax-self.PA.y_origin)*(fj-self.PA.fj_origin)/(self.PA.fjmax-self.PA.fj_origin)
            x,y = self.PA.get_xy_at_fifj( fi, fj )
            
            if iave<Nsteps/4 or iave>Nsteps*3/4:
                print('Rejected fi=%g, fj=%g, x=%g, y=%g'%(fi,fj,x,y))
            else:

                f_ipos = w * fi
                i = int( f_ipos )
                f_jpos = h * fj
                j = int( f_jpos )
                draw_rgb.rectangle(((i-4,j-4),(i+4,j+4)), fill='green', outline ="green") 
                draw_rgb_mask.rectangle(((i-4,j-4),(i+4,j+4)), fill=self.opacity, outline =self.opacity) 
                
                
                self.calc_pointL.append( (x,y, fi,fj) )

        # plot selected curve
        fiL = []
        fjL = []
        fsL = [0.0] # approximate length along curve
        for i,pL in enumerate(self.calc_pointL):
            #print(pL)
            x,y,fi,fj = pL
            fiL.append( fi )
            fjL.append( fj )
            if i>0:
                s = fsL[-1] +  ((fi-fiL[-2])**2 + (fj-fjL[-2])**2)**0.5
                fsL.append( s )
        s_total = fsL[-1]        
        
        # build interplators along curve
        fjterp = InterpProp( fiL, fjL, extrapOK=True )
        fi_sterp = InterpProp( fsL, fiL, extrapOK=True )
            
        # draw curve
        ijL = [] # list of (i,j) for draw.line
        for i in range(101):
            s = i*s_total / 100.0
            fi = fi_sterp( s )
            
            fj = fjterp( fi )
            ijL.append( (int( w * fi ), int( h * fj )) )

        draw_rgb.line( ijL, width=3, fill='red' )
        draw_rgb_mask.line( ijL, width=3, fill=self.opacity )
        

        # make rgb image for display to user
        if self.Checkbutton_2_StringVar.get() == 'yes':
            show_img = show_gray.convert("RGBA")
        else:
            show_img = gray.convert("RGBA")
        show_img.paste(rgb, mask=rgb_mask)
        
        
        self.PA.img = show_img


    def MouseWheelHandler(self, event):
        #print('MouseWheelHandler event.num =', event.num)

        if event.num == 5 or event.delta < 0:
            result = -1 
            #self.PA.zoom_in(zoom_factor=0.1)
            self.PA.zoom_into_ij(event.x, event.y, zoom_factor=0.1)
        else:
            result = 1 
            #self.PA.zoom_out(zoom_factor=0.1)
            self.PA.zoom_out_from_ij(event.x, event.y, zoom_factor=0.1)
            
        self.fill_canvas()

    def Canvas_Begin_End_Drag(self, event):
        self.is_dragging = not self.is_dragging
        ix = int(event.x)
        iy = int(event.y)
        
        self.last_right_click_pos = (ix, iy)
        
    def Canvas_Drag_Axes(self, event):
        di = self.last_right_click_pos[0] - event.x
        dj = self.last_right_click_pos[1] - event.y
        self.PA.adjust_offset(di, dj)
        
        self.last_right_click_pos = (event.x, event.y)
        
        self.fill_canvas()

    def Canvas_Enter(self, event):
        if self.dw_canv > 0 and self.need_resize:
            #print('Resizing Canvas',w-self.dw_canv, h-self.dh_canv)
            self.Canvas_1.config(width=self.w-self.dw_canv, height=self.h-self.dh_canv)
            self.PA.set_canvas_wh(self.w-self.dw_canv, self.h-self.dh_canv)
            #self.fill_canvas()
            self.need_resize = False
        
        
        self.in_canvas = True
        self.fill_canvas()
                
    def Canvas_Leave(self, event):
        self.in_canvas = False
        self.fill_canvas()

    def Canvas_Hover(self, event):
        self.last_hover_pos = (event.x, event.y)
        self.fill_canvas()
            
    def bindConfigure(self, event):
        if not self.initComplete:
            #print('Init Master_Configure')
            self.dialog_master.bind("<Configure>", self.Master_Configure)
            self.initComplete = 1


    def Master_Configure(self, event):
        pass
        # replace, delete, or comment-out the following
        if event.widget != self.dialog_master:
            if self.w != -1:
                return
        #print('Master_Configure', event)
        x = int(self.winfo_x())
        y = int(self.winfo_y())
        w = int(self.winfo_width())
        h = int(self.winfo_height())
        if (self.x, self.y, self.w, self.h) == (-1,-1,-1,-1):
            self.x, self.y, self.w, self.h = x,y,w,h
            
            w_canv = int( self.Canvas_1.winfo_width() )
            h_canv = int( self.Canvas_1.winfo_height() )
            self.dw_canv = w - w_canv
            self.dh_canv = h - h_canv
            


        if self.w!=w or self.h!=h:
            #print( "Master reconfigured... make resize adjustments")
            self.w=w
            self.h=h
            self.need_resize = True
            
            #if self.dw_canv > 0:
            #    #print('Resizing Canvas',w-self.dw_canv, h-self.dh_canv)
            #    self.Canvas_1.config(width=w-self.dw_canv, height=h-self.dh_canv)
            #    self.PA.set_canvas_wh(w-self.dw_canv, h-self.dh_canv)
            #    self.fill_canvas()
        

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Canvas_1"
    def make_Canvas_1(self, frame):
        """      Canvas:  at Main(2,2)"""
        self.Canvas_1 = Canvas( frame , width="600", height="500")
        self.Canvas_1.grid(row=2, column=2, sticky="nsew")

        # >>>>>>insert any user code below this comment for section "make_Canvas_1"

        self.Canvas_1.config(bg='#ffffcc')
        self.Canvas_1.bind("<ButtonRelease-1>", self.Canvas_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Frame_1"
    def make_Frame_1(self, frame):
        """       Frame:  at Main(2,1)"""
        self.Frame_1 = Frame( frame , width="60", height="50")
        self.Frame_1.grid(row=2, column=1, sticky="ns")

        # >>>>>>insert any user code below this comment for section "make_Frame_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_1"
    def make_Button_1(self, frame):
        """      Button: Generate Points : at Frame_1(8,1)"""
        self.Button_1 = Button( frame , text="Generate Points", width="15")
        self.Button_1.grid(row=8, column=1)

        # >>>>>>insert any user code below this comment for section "make_Button_1"

        self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Checkbutton_1"
    def make_Checkbutton_1(self, frame):
        """ Checkbutton: Replace or Add : at Frame_1(10,1)"""
        self.Checkbutton_1 = Checkbutton( frame , text="Replace or Add", width="15", justify="left", anchor="w")
        self.Checkbutton_1.grid(row=10, column=1, sticky="w")
        self.Checkbutton_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Checkbutton_1"

        self.Checkbutton_1.configure(variable=self.Checkbutton_1_StringVar, onvalue="yes", offvalue="no")
        self.Checkbutton_1_StringVar.set("yes")
        self.Checkbutton_1_StringVar_traceName = self.Checkbutton_1_StringVar.trace_variable("w", self.Checkbutton_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Checkbutton_2"
    def make_Checkbutton_2(self, frame):
        """ Checkbutton: Show Blur : at Frame_1(9,1)"""
        self.Checkbutton_2 = Checkbutton( frame , text="Show Blur", width="15", justify="left", anchor="w")
        self.Checkbutton_2.grid(row=9, column=1, sticky="w")
        self.Checkbutton_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Checkbutton_2"

        self.Checkbutton_2.configure(variable=self.Checkbutton_2_StringVar, onvalue="yes", offvalue="no")
        self.Checkbutton_2_StringVar.set("no")
        self.Checkbutton_2_StringVar_traceName = self.Checkbutton_2_StringVar.trace_variable("w", self.Checkbutton_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1"
    def make_Entry_1(self, frame):
        """       Entry: 0.02 : at Frame_1(5,1)"""
        self.Entry_1 = Entry( frame , width="17")
        self.Entry_1.grid(row=5, column=1, sticky="e")
        self.Entry_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Entry_1"
        self.Entry_1_StringVar.set( '0.02' )
        self.Entry_1.configure(textvariable=self.Entry_1_StringVar)
        self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable("w", self.Entry_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1"
    def make_Label_1(self, frame):
        """       Label: Blur Radius : at Frame_1(0,1)"""
        self.Label_1 = Label( frame , text="Blur Radius", width="15", anchor="w", justify="left")
        self.Label_1.grid(row=0, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_1"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2"
    def make_Label_2(self, frame):
        """       Label: #Generated Points : at Frame_1(2,1)"""
        self.Label_2 = Label( frame , text="#Point Intervals", width="15", anchor="w", justify="left")
        self.Label_2.grid(row=2, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_2"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3"
    def make_Label_3(self, frame):
        """       Label: Explore Fraction : at Frame_1(4,1)"""
        self.Label_3 = Label( frame , text="Explore Fraction", width="15", anchor="w", justify="left")
        self.Label_3.grid(row=4, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_3"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4"
    def make_Label_4(self, frame):
        """       Label: Masking Line Width : at Frame_1(6,1)"""
        self.Label_4 = Label( frame , text="Masking Line Width", width="15", anchor="w", justify="left")
        self.Label_4.grid(row=6, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_4"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5"
    def make_Label_5(self, frame):
        """       Label: Point Opacity : at Frame_1(11,1)"""
        self.Label_5 = Label( frame , text="Point Opacity", width="15", anchor="w", justify="left")
        self.Label_5.grid(row=11, column=1, sticky="w")

        # >>>>>>insert any user code below this comment for section "make_Label_5"


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_1"
    def make_Spinbox_1(self, frame):
        """     Spinbox: Blur Radius : at Frame_1(1,1)"""
        self.Spinbox_1 = Spinbox( frame , from_="1", to="10", text="Blur Radius", width="15")
        self.Spinbox_1.grid(row=1, column=1, sticky="e")
        self.Spinbox_1_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Spinbox_1"

        self.Spinbox_1.configure(textvariable=self.Spinbox_1_StringVar, from_="1", to="10")
        self.Spinbox_1_StringVar.set("3")
        self.Spinbox_1_StringVar_traceName = self.Spinbox_1_StringVar.trace_variable("w", self.Spinbox_1_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_2"
    def make_Spinbox_2(self, frame):
        """     Spinbox: 3 to 1000 : at Frame_1(3,1)"""
        self.Spinbox_2 = Spinbox( frame , from_="3", to="1000", text="Spinbox_2", width="15")
        self.Spinbox_2.grid(row=3, column=1, sticky="e")
        self.Spinbox_2_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Spinbox_2"

        self.Spinbox_2.configure(textvariable=self.Spinbox_2_StringVar, from_="3", to="1000")
        self.Spinbox_2_StringVar.set("12")
        self.Spinbox_2_StringVar_traceName = self.Spinbox_2_StringVar.trace_variable("w", self.Spinbox_2_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_3"
    def make_Spinbox_3(self, frame):
        """     Spinbox: 1 to 9 : at Frame_1(7,1)"""
        self.Spinbox_3 = Spinbox( frame , from_="1", to="9", text="Spinbox_3", width="15")
        self.Spinbox_3.grid(row=7, column=1, sticky="e")
        self.Spinbox_3_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Spinbox_3"

        self.Spinbox_3.configure(textvariable=self.Spinbox_3_StringVar, from_="1", to="25")
        self.Spinbox_3_StringVar.set("9")
        self.Spinbox_3_StringVar_traceName = self.Spinbox_3_StringVar.trace_variable("w", self.Spinbox_3_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_4"
    def make_Spinbox_4(self, frame):
        """     Spinbox: 1 to 255 : at Frame_1(12,1)"""
        self.Spinbox_4 = Spinbox( frame , from_="1", to="255", text="Spinbox_4", width="15")
        self.Spinbox_4.grid(row=12, column=1, sticky="e")
        self.Spinbox_4_StringVar = StringVar()

        # >>>>>>insert any user code below this comment for section "make_Spinbox_4"

        self.Spinbox_4.configure(textvariable=self.Spinbox_4_StringVar, from_="10", to="255")
        self.Spinbox_4_StringVar.set("155")
        self.Spinbox_4_StringVar_traceName = self.Spinbox_4_StringVar.trace_variable("w", self.Spinbox_4_StringVar_Callback)

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Text_1"
    def make_Text_1(self, frame):
        """        Text:  at Frame_1(13,1)"""
        self.Text_1 = Text( frame , width="15", height="15")
        self.Text_1.grid(row=13, column=1, sticky="ns")

        # >>>>>>insert any user code below this comment for section "make_Text_1"
        self.Text_1 = Text( frame , width="15") # redefine w/o height attribute.
        self.Text_1.grid(row=13, column=1, sticky="ns")
        self.Text_1.insert('1.0', text_warn)


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Canvas_1_Click"
    def Canvas_1_Click(self, event): #bind method for component ID=Canvas_1
        """      Canvas:  at Main(2,2)"""
        pass
        # >>>>>>insert any user code below this comment for section "Canvas_1_Click"
        # replace, delete, or comment-out the following
        #print( "executed method Canvas_1_Click" )

        #print( "clicked in canvas at x,y =",event.x,event.y )
        w = int(self.Canvas_1.cget("width"))
        h = int(self.Canvas_1.cget("height"))
        #self.Canvas_1.create_rectangle((2, 2, w+1, h+1), outline="blue")
        #self.Canvas_1.create_line(0, 0, w+2, h+2, fill="red")
        #x = int(event.x)
        #y = int(event.y)
        #print( "event x,y=",x,y )
        #self.Canvas_1.create_text(x,y, text="NE", fill="green", anchor=NE)
        #self.Canvas_1.create_text(x,y, text="SW", fill="magenta", anchor=SW)
        
    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_1_Click"
    def Button_1_Click(self, event): #bind method for component ID=Button_1
        """      Button: Generate Points : at Frame_1(8,1)"""
        pass
        # >>>>>>insert any user code below this comment for section "Button_1_Click"
        # replace, delete, or comment-out the following
        #print( "executed method Button_1_Click" )
        
        self.fill_canvas()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Checkbutton_1_StringVar_traceName"
    def Checkbutton_1_StringVar_Callback(self, varName, index, mode):
        """ Checkbutton: Replace or Add : at Frame_1(10,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Checkbutton_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Checkbutton_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Checkbutton_1_StringVar.get() )
        
        self.Text_1.delete('1.0', END)
        if self.Checkbutton_1_StringVar.get() == 'yes':
            self.Text_1.insert('1.0', text_warn)
        else:
            self.Text_1.insert('1.0', text_info)



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Checkbutton_2_StringVar_traceName"
    def Checkbutton_2_StringVar_Callback(self, varName, index, mode):
        """ Checkbutton: Show Blur : at Frame_1(9,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Checkbutton_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Checkbutton_2_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Checkbutton_2_StringVar.get() )

        
        self.fill_canvas()


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName"
    def Entry_1_StringVar_Callback(self, varName, index, mode):
        """       Entry: 0.02 : at Frame_1(5,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Entry_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Entry_1_StringVar.get() )

        try:
            self.d_frac = float( self.Entry_1_StringVar.get() )
        except:
            self.d_frac = 0.02


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_1_StringVar_traceName"
    def Spinbox_1_StringVar_Callback(self, varName, index, mode):
        """     Spinbox: Blur Radius : at Frame_1(1,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Spinbox_1_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Spinbox_1_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Spinbox_1_StringVar.get() )

        try:
            self.blur_radius = int( self.Spinbox_1_StringVar.get() )
        except:
            self.blur_radius = 3
        self.fill_canvas()

    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_2_StringVar_traceName"
    def Spinbox_2_StringVar_Callback(self, varName, index, mode):
        """     Spinbox: 3 to 1000 : at Frame_1(3,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Spinbox_2_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Spinbox_2_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Spinbox_2_StringVar.get() )

        try:
            self.num_points = int( self.Spinbox_2_StringVar.get() )
        except:
            self.num_points = 20
        self.fill_canvas()


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_3_StringVar_traceName"
    def Spinbox_3_StringVar_Callback(self, varName, index, mode):
        """     Spinbox: 1 to 9 : at Frame_1(7,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Spinbox_3_StringVar_traceName"
        # replace, delete, or comment-out the following
        #print( "Spinbox_3_StringVar_Callback varName, index, mode",varName, index, mode )
        #print( "    new StringVar value =",self.Spinbox_3_StringVar.get() )
        MAX_SIZE = 25
        
        new_val = int( self.Spinbox_3_StringVar.get() )
        if new_val %2 == 1:
            self.masking_line_size = new_val
        elif new_val > self.masking_line_size and new_val < MAX_SIZE:
            self.masking_line_size = new_val + 1
            self.Spinbox_3_StringVar.set( new_val+1 )
        elif new_val < self.masking_line_size and new_val > 0:
            self.masking_line_size = new_val - 1
            self.Spinbox_3_StringVar.set( new_val-1 )
        elif new_val >= MAX_SIZE:
            self.masking_line_size = MAX_SIZE
            self.Spinbox_3_StringVar.set( MAX_SIZE )
            
        #print('self.masking_line_size =',self.masking_line_size)
        self.fill_canvas()



    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_4_StringVar_traceName"
    def Spinbox_4_StringVar_Callback(self, varName, index, mode):
        """     Spinbox: 1 to 255 : at Frame_1(12,1)"""
        pass

        # >>>>>>insert any user code below this comment for section "Spinbox_4_StringVar_traceName"
        # replace, delete, or comment-out the following
        print( "Spinbox_4_StringVar_Callback varName, index, mode",varName, index, mode )
        print( "    new StringVar value =",self.Spinbox_4_StringVar.get() )

        self.opacity = int( self.Spinbox_4_StringVar.get() )


    # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate"
    def validate(self):
        self.result = {} # return a dictionary of results
    

        self.result["Checkbutton_1"] = self.Checkbutton_1_StringVar.get()
        self.result["Checkbutton_2"] = self.Checkbutton_2_StringVar.get()
        self.result["Entry_1"] = self.Entry_1_StringVar.get()
        self.result["Spinbox_1"] = self.Spinbox_1_StringVar.get()
        self.result["Spinbox_2"] = self.Spinbox_2_StringVar.get()
        self.result["Spinbox_3"] = self.Spinbox_3_StringVar.get()
        self.result["Spinbox_4"] = self.Spinbox_4_StringVar.get()

        # >>>>>>insert any user code below this comment for section "dialog_validate"
        # set values in "self.result" dictionary for return
        # for example...
        # self.result["age"] = self.Entry_2_StringVar.get() 


        self.result["replace_pts"] = self.Checkbutton_1_StringVar.get()
        self.result["calc_pointL"] = self.calc_pointL
        return 1
# TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end"


    def apply(self):
        pass
        #print( 'apply called' )

class _Testdialog:
    def __init__(self, master):
        frame = Frame(master, width=300, height=300)
        frame.pack()
        self.master = master
        self.x, self.y, self.w, self.h = -1,-1,-1,-1
        
        self.Button_1 = Button(text="Test Dialog", relief="raised", width="15")
        self.Button_1.place(x=84, y=36)
        self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click)

    def Button_1_Click(self, event): #click method for component ID=1
        dialog = _auto_detect(self.master, "Test Dialog")
        print( '===============Result from Dialog====================' )
        print( dialog.result )
        print( '=====================================================' )

def main():
    root = Tk()
    app = _Testdialog(root)
    root.mainloop()

if __name__ == '__main__':
    main()
