#!/usr/bin/python3

import sys
import time

import traceback

from lib.cprint import cprint
import __main__ as MAIN
import _thread as thread

import lib.showlib as showlib
import lib.fxlib as fxlib
import lib.libtk as libtk
import tkgui.dialog as dialoglib
import lib.tkrefresh as tkrefresh
import lib.fixlib as fixlib

from idlelib.tooltip import Hovertip
#myTip = Hovertip(b,'Strg + S ')

dialog = dialoglib.Dialog()

class tk_event():
    """ global input event Handeler for short cut's ... etc
    """
    def __init__(self,fix,elem,attr=None,data=None,mode=None):
        self.fix = fix
        self.data=data
        self.attr = attr
        self.elem = elem
        self.mode = mode

    def setup(self,event):       
        cprint("tk_event.SETUP",[self.mode,self.attr],color="red")
        if self.mode != "SETUP":
            return 0

        if self.attr == "SAVE\nSHOW":
            self.elem["bg"] = "orange"
            self.elem["text"] = "SAVING..."
            self.elem["bg"] = "red"
            self.elem.config(activebackground="orange")

            MAIN.save_show()
            MAIN.modes.val(self.attr,1)

            self.elem["bg"] = "lightgrey"
            self.elem.config(activebackground="lightgrey")
            b = libtk.BLINKI(self.elem)
            b.blink()
            self.elem["text"] = "SAVE\nSHOW"
            def xxyy():
                time.sleep(3)
                MAIN.modes.val(self.attr,0)
            thread.start_new_thread(xxyy,())
        elif self.attr == "LOAD\nSHOW":
            name = "LOAD-SHOW"
            line1 = "PATH: " + showlib.current_show_path()
            line2 = "DATE: " + time.strftime("%Y-%m-%d %X",  time.localtime(time.time()))

            class cb():
                def __init__(self,name=""):
                    self.name=name
                    cprint("   LOAD-SHOW.init",name)
                def cb(self,event=None,**args):
                    cprint("   LOAD-SHOW.cdb",self.name,event,args)
                    if self.name != "<exit>":
                        cprint("-----------------------:")
                        MAIN.LOAD_SHOW_AND_RESTART(self.name).cb()

            pw = libtk.PopupList(name,cb=cb)
            print(line1,line2)
            frame = pw.sframe(line1=line1,line2=line2)
            r = libtk.frame_of_show_list(frame,cb=cb)

        elif self.attr == "NEW\nSHOW":

            def _cb(data):
                if not data:
                    cprint("err443",self,"_cb",data)
                    return None
                fname = data["Value"]
                fpath = showlib.generate_show_path(fname)
                cprint("SAVE NEW SHOW",fpath,fname)

                if MAIN.save_show_as(fname,new=1):
                    MAIN.LOAD_SHOW_AND_RESTART(fname).cb() 

            dialog._cb = _cb
            dialog.askstring("CREATE NEW SHOW","CREATE NEW SHOW:")

        elif self.attr == "SAVE\nSHOW AS":

            #def _cb(fname):
            def _cb(data):
                if not data:
                    cprint("err443",self,"_cb",data)
                    return None
                fname = data["Value"]

                if MAIN.save_show_as(fname):
                    MAIN.LOAD_SHOW_AND_RESTART(fname).cb() 


            dialog._cb = _cb
            dialog.askstring("SAVE SHOW AS","SAVE SHOW AS:")

        elif self.attr == "SAVE &\nRESTART":
            self.elem["bg"] = "orange"
            self.elem["text"] = "SAVING..."
            self.elem["bg"] = "red"
            self.elem.config(activebackground="orange")

            MAIN.save_show()

            self.elem["text"] = "RESTARTING..."
            self.elem["bg"] = "lightgrey"
            self.elem.config(activebackground="lightgrey")

            MAIN.modes.val(self.attr,1)
            MAIN.LOAD_SHOW_AND_RESTART("").cb(force=1)

        elif self.attr == "DRAW\nGUI":
            old_text = self.elem["text"]
            window_manager.top("PATCH")
            gui_patch.draw(MAIN.FIXTURES)
            gui_fix.draw(MAIN.FIXTURES)
            window_manager.top("MAIN.FIXTURES")
            MAIN.master._refresh_exec()
            self.elem["text"] = old_text  

        elif self.attr == "PRO\nMODE":
            MAIN.save_show()
            MAIN.modes.val(self.attr,1)
            time.sleep(1)
            print("SETUP",[self.attr])
            import lib.restart as restart
            restart.pro()

        elif self.attr == "EASY\nMODE":
            MAIN.save_show()
            MAIN.modes.val(self.attr,1)
            time.sleep(1)
            print("SETUP",[self.attr])
            import lib.restart as restart
            restart.easy()
        else:
            if IS_GUI:
                msg="{}\nnot implemented".format(self.attr.replace("\n"," "))
                r=tkinter.messagebox.showwarning(message=msg,parent=None)
        return 1

    def live(self,event):       
        if self.mode != "LIVE":
            return 0
                
        if "FADE" in self.attr or "DELAY" in self.attr:
            ct =None
            if self.attr == "FADE":
                ct = MAIN.meta.FADE
            elif self.attr == "DELAY":
                ct = MAIN.meta.DELAY
            elif "PAN/TILT\nFADE" in self.attr:
                ct = MAIN.meta.FADE_move
            elif "PAN/TILT\nDELAY" in self.attr:
                ct = MAIN.meta.FADE_move_delay
            if ct is None:
                cprint("err live",[self.attr],color="red")
                cprint(" ",ct,color="red")
                return
            value = ct.val()
            cprint("EVENT CHANGE:",[self.mode,value,self.attr])
    
            b = None        
            if MAIN.meta.live_prm.elem[self.attr]:
                b = MAIN.meta.live_prm.elem[self.attr]
            if b is None:
                cprint("err LIVE live_prm has no elem:",self.attr,color="red")
                return 0

            if event.num == 1:
                v = ct.toggle()
                if v:
                    b["bg"] = "grey"
                    b.config(activebackground="grey")
                else:
                    b["bg"] = "green"
                    b.config(activebackground="lightgreen")
            elif event.num == 2:
                ct.invert()
            elif event.num == 3:
                ct.reset()
            elif event.num == 4:
                ct.inc() 
            elif event.num == 5:
                ct.dec()

            value = ct.val()


            b["text"] = ct.format()
            #if self.attr == "FADE":
            #    b["text"] = "FADE:\n{:0.2f}".format(value)
            #elif self.attr == "DELAY":
            #    b["text"] = "DELAY:\n{:0.2f}".format(value)
            #elif "PAN/TILT\nFADE" in self.attr:
            #    b["text"] = "PAN/TILT\nFADE:{:0.2f}".format(value)
            #elif "PAN/TILT\nDELAY" in self.attr:
            #    b["text"] = "PAN/TILT\nD:{:0.2f}".format(value)



    def command(self,event):       
        if self.mode != "COMMAND":
            return 0

        if self.attr == "CLEAR":
            if event.num == 1:
                ok = fixlib.clear(MAIN.FIXTURES.fixtures)
                if ok:
                    MAIN.master._refresh_fix()
                MAIN.modes.val(self.attr,0)

        elif self.attr == "SAVE":
            MAIN.modes.val(self.attr,1)
            MAIN.save_show()
            #MAIN.EXEC.backup_exec()
            #MAIN.FIXTURES.backup_patch()
            #time.sleep(1)
            MAIN.modes.val(self.attr,0)

        elif self.attr == "S-KEY":
            if MAIN._global_short_key:
                MAIN._global_short_key = 0
                MAIN.meta.commands.elem["S-KEY"]["bg"] = "red"
                MAIN.meta.commands.elem["S-KEY"]["activebackground"] = "red"
            else:
                MAIN._global_short_key = 1
                MAIN.meta.commands.elem["S-KEY"]["bg"] = "green"
                MAIN.meta.commands.elem["S-KEY"]["activebackground"] = "green"
            cprint("s-key",MAIN._global_short_key)

        else:
            if event.num == 1:
                cprint("ELSE",self.attr)
                MAIN.modes.val(self.attr,1)

        return 0


    def encoder(self,event):
        cprint("tk_event","ENC",self.fix,self.attr,self.mode)
        cprint("SHIFT_KEY",MAIN._shift_key,"??????????")

        if self.mode == "ENCODER":
            if self._encoder(event):
                MAIN.master.refresh_fix() # delayed
                MAIN.refresher_fix.reset() # = tkrefresh.Refresher()

        if self.mode == "ENCODER2":
            if self._encoder(event):
                MAIN.master.refresh_fix() # delayed
                MAIN.refresher_fix.reset() # = tkrefresh.Refresher()

        if self.mode == "INVERT":
            cprint("INVERT",event)
            if self._encoder(event):
                MAIN.master.refresh_fix() # delayed
                MAIN.refresher_fix.reset() # = tkrefresh.Refresher()

    def _encoder(self,event):

        cprint("-- tk_event","_ENC",self.fix,self.attr,self.mode)
        cprint("-- SHIFT_KEY",MAIN._shift_key,"??????????")
        val=""
        if event.num == 1:
            val ="click"
        elif event.num == 4:
            val ="++"
            if MAIN._shift_key:
                val = "+"
        elif event.num == 5:
            val ="--"
            if MAIN._shift_key:
                val = "-"
        #print("SHIFT",val,MAIN._shift_key)
        if val:
            fixlib.encoder(MAIN.FIXTURES.fixtures,fix=self.fix,attr=self.attr,xval=val)
            return 1       


            
    def cb(self,event):
        cprint("EVENT cb",[self.attr],self.mode,event,color='yellow')
        cprint(["type",event.type,"num",event.num])

        MAIN.INIT_OK = 1
        try:
            change = 0
            if "keysym" in dir(event):
                if "Escape" == event.keysym:
                    ok = fixlib.clear(MAIN.FIXTURES.fixtures)
                    MAIN.master._refresh_fix()
                    cprint()
                    return 0

            if self.mode == "SETUP":
                self.setup(event)
            elif self.mode == "COMMAND":
                self.command(event)
            elif self.mode == "LIVE":
                self.live(event)
            elif self.mode == "ENCODER":
                self.encoder(event)
                MAIN.master.refresh_fix()

            elif self.mode == "ENCODER2":
                self.encoder(event)
            elif self.mode == "INVERT":
                self.encoder(event)
            elif self.mode == "FX":
                cprint("tk_event CALLING FX WRONG EVENT OBJECT !!",color="red")
            elif self.mode == "ROOT":
                if event.keysym=="Escape":
                    pass

            elif self.mode == "INPUT":
                cprint("INP",self.data.entry.get())
                if event.keycode == 36:
                    x=self.data.entry.get()
                    #client.send(x)

            elif self.mode == "INPUT2":
                cprint("INP2",self.data.entry2.get())
                if event.keycode == 36:
                    x=self.data.entry2.get()
                    #client.send(x)

            elif self.mode == "INPUT3":
                cprint("INP3",self.data.entry3.get())
                if event.keycode == 36:
                    x=self.data.entry3.get()
                    #client.send(x)

            elif self.mode == "EXEC":
                nr = self.attr #int(self.attr.split(":")[1])-1

                if event.num == 3: # right click for testing
                    if str(event.type) == '4': #4 ButtonPress
                        if MAIN.modes.val("CFG-BTN"):
                            MAIN.master.btn_cfg(nr,testing=1)

                if event.num == 1:
                    if str(event.type) == '4': #4 ButtonPress
                        if MAIN.modes.val("REC"):
                            self.data.exec_rec(nr)
                            MAIN.modes.val("REC",0)
                            time.sleep(0.05)
                            MAIN.master._refresh_exec(nr=nr)
                        elif MAIN.modes.val("DEL"):
                            ok=MAIN.EXEC.delete(nr)
                            if ok:
                                MAIN.modes.val("DEL",0)
                                #MAIN.master.refresh_exec()
                                MAIN.master._refresh_exec(nr=nr)
                        elif MAIN.modes.val("COPY"):
                            ok=MAIN.EXEC.copy(nr)
                            if ok:
                                MAIN.modes.val("COPY",0)
                                MAIN.master._refresh_exec(nr=nr)
                        elif MAIN.modes.val("MOVE"):
                            ok,cnr,bnr=MAIN.EXEC.move(nr)
                            if ok:
                                #MAIN.modes.val("MOVE",0) # keep MOVE on
                                MAIN.master._refresh_exec(nr=nr)
                                MAIN.master._refresh_exec(nr=bnr)
                        elif MAIN.modes.val("CFG-BTN"):
                            MAIN.master.btn_cfg(nr)
                            #MAIN.master._refresh_exec(nr=nr)
                        elif MAIN.modes.val("LABEL"):#else:
                            MAIN.master.label(nr)
                            #MAIN.master._refresh_exec(nr=nr)

                        elif MAIN.modes.val("EDIT"):
                            fixlib.clear(MAIN.FIXTURES.fixtures)
                            self.data.exec_select(nr)
                            self.data.exec_go(nr,xfade=0,event=event,val=255,button="go")
                            MAIN.modes.val("EDIT", 0)
                            MAIN.master.refresh_fix()
                            MAIN.refresher_fix.reset() # = tkrefresh.Refresher()

                        elif MAIN.modes.val("SELECT"):
                            self.data.exec_select(nr)
                        else:
                            self.data.exec_go(nr,event=event,val=255)
                    else:
                        self.data.exec_go(nr,xfade=0,event=event,val=0)
                        #cprint(" == "*10)
                        MAIN.master.refresh_fix()
                        MAIN.refresher_fix.reset() # = tkrefresh.Refresher()

                        
                if event.num == 3:
                    if not MAIN.modes.val("REC"):
                        if str(event.type) == '4': #4 ButtonPress
                            self.data.exec_go(nr,xfade=0,ptfade=0,event=event,val=255)
                        else:
                            self.data.exec_go(nr,xfade=0,ptfade=0,event=event,val=0)
                        
                cprint()
                return 0
            elif self.mode == "INPUT":
                cprint()
                return 0

        except Exception as e:
            cprint("== cb EXCEPT",e,color="red")
            cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
            cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red")
        cprint()
        return 1 

class tk_event_fx():
    """ global input event Handeler for short cut's ... etc
    """
    def __init__(self,fix,elem,attr=None,data=None,mode=None):
        self.fix = fix
        self.data = data # gui / master
        self.attr = attr
        self.elem = elem
        self.mode = mode
        self.ATTR_GRP = ""

    def fx(self,event):
        cprint("Xevent.fx",self.attr,self.fix,event)
        fx2 = {}

        if self.attr == "FX:RED":
            if event.num == 4:
                cprint("FX:COLOR CHANGE",MAIN.meta.fx_prm,color="red")
                txt = "FX:RED" 
                MAIN.meta.fx_prm["MODE"] += 1
                if MAIN.meta.fx_prm["MODE"] >= len(MAIN.meta.fx_modes):
                    MAIN.meta.fx_prm["MODE"]=0
                txt = "FX:\n"+MAIN.meta.fx_modes[MAIN.meta.fx_prm["MODE"]]

                MAIN.meta.fx_color.elem["FX:RED"]["text"] = txt
            elif event.num == 5:
                cprint("FX:COLOR CHANGE",MAIN.meta.fx_prm,color="red")
                txt = "FX:RED" 
                MAIN.meta.fx_prm["MODE"] -= 1
                if MAIN.meta.fx_prm["MODE"] < 0:
                    MAIN.meta.fx_prm["MODE"]= len(MAIN.meta.fx_modes)-1
                txt = "FX:\n"+MAIN.meta.fx_modes[MAIN.meta.fx_prm["MODE"]]
                MAIN.meta.fx_color.elem["FX:RED"]["text"] = txt

        if self.attr.startswith("2D"):
            if event.num == 4:
                cprint("2D-X: CHANGE",MAIN.meta.fx_prm,color="red")
                txt = "2D-X:" 
                MAIN.meta.fx_prm["2D:MODE"] += 1
                if MAIN.meta.fx_prm["2D:MODE"] >= len(MAIN.meta.fx_x_modes):
                    MAIN.meta.fx_prm["2D:MODE"]=0
                txt = "2D:MODE\n"+MAIN.meta.fx_x_modes[MAIN.meta.fx_prm["2D:MODE"]]

                MAIN.meta.fx_cfg.elem["2D:MODE"]["text"] = txt
            elif event.num == 5:
                cprint("2D-X: CHANGE",MAIN.meta.fx_prm,color="red")
                txt = "2D-X:" 
                MAIN.meta.fx_prm["2D:MODE"] -= 1
                if MAIN.meta.fx_prm["2D:MODE"] < 0:
                    MAIN.meta.fx_prm["2D:MODE"]= len(MAIN.meta.fx_x_modes)-1
                txt = "2D:MODE\n"+MAIN.meta.fx_x_modes[MAIN.meta.fx_prm["2D:MODE"]]
                MAIN.meta.fx_cfg.elem["2D:MODE"]["text"] = txt

        elif event.num == 1:
            xfixtures = []
            fix_active =fixlib.get_active(MAIN.FIXTURES.fixtures) 
            for fix in fix_active:
                if fix == "CFG":
                    continue
                xfixtures.append(fix)

            if not xfixtures:
                cprint("470 fx() ... init no fixture selected",color="red")
                return 0
            
            
            xfixtures   = MAIN.process_matrix(xfixtures)
            wing_buffer = fxlib.process_wings(xfixtures,MAIN.meta.fx_prm)
            fxlib.process_effect(
                        wing_buffer,MAIN.meta.fx_prm,MAIN.meta.fx_prm_move,MAIN.modes,
                        MAIN.jclient_send,MAIN.master,
                        MAIN.FIXTURES,fx_name=self.attr
                        )




    def command(self,event,mode=""):       
        cprint("tkevent.tk_event_fx.command")
        cprint(" ",self.mode)
        prm = None
        ct = None
        if self.mode == "FX":
            prm = MAIN.meta.fx_prm
            ct  = MAIN.meta.fx_cfg
        if self.mode == "FX-MOVE":
            prm = MAIN.meta.fx_prm_move
            ct = MAIN.meta.fx_moves 
        if self.mode == "FX-3":
            prm = [] #MAIN.meta.fx_prm
            ct  = "" #MAIN.meta.fx_cfg
            cprint("--",self,"FX-3",color="red")
            print(" --", self.attr)
            fx3_grid = MAIN.meta.fx3_grid # OptionBuffer()
            if self.attr not in fx3_grid:
                return

            fx3_buf = fx3_grid[self.attr]
            col = self.attr.split(":")[1]
            print(fx3_buf)

            if self.attr.startswith("ATTR:"):
                fx_func1 = MAIN.meta.fx3_grid["GRP:"+str(col)]
                GRP = fx_func1.val()
                if GRP != self.ATTR_GRP:
                    self.ATTR_GRP = GRP
                    fx_func1.val(GRP)
                    MAIN.meta.fx3_grid[self.attr] = MAIN.meta.Optionbuffer_create_ATTR(GRP)
                fx_func = MAIN.meta.fx3_grid[self.attr] 
                fx_func.data["wrap"] = 1
                fx_func.inc()
                v=fx_func.val()
                print(v)
                print(self.elem)
                self.elem["text"] = v
            else: #if self.attr.startswith("TYPE:"):
                fx_func = MAIN.meta.fx3_grid[self.attr]
                fx_func.data["wrap"] = 1
                fx_func.inc()
                v=fx_func.val()
                print(v)
                print(self.elem)
                self.elem["text"] = v
            return

        if 1:
            cprint("---", self.attr,"!!",prm ,color="red")
            if self.attr.startswith("SIZE:"):#SIN":
                #global MAIN.meta.fx_prm
                k = "SIZE"
                p = prm[k]
                if event.num == 1:
                    _stats = [0,30,100,255]
                    if p in _stats:
                        idx = _stats.index(p)+1
                        if idx > len(_stats)-1: #rotate
                            idx = 0
                        p = _stats[idx]
                    else:
                        p = _stats[1]
                elif event.num == 3:
                    p =100
                elif event.num == 4:
                    if p <= 0:
                        p = 1
                    p +=5
                elif event.num == 5:
                    p -=5
                #p =int(p)
                
                if p > 4000:
                    p = 4000
                if p < 0:
                    p =0
                if p == 6: #bug
                    p =5
                ct.elem[self.attr]["text"] = "SIZE:\n{:0.0f}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("SPEED:"):#SIN":
                #global prm
                k = "SPEED"
                p = prm[k]
                if event.num == 1:
                    _stats = [0,5,25,30,100,255]
                    if p in _stats:
                        idx = _stats.index(p)+1
                        if idx > len(_stats)-1: #rotate
                            idx = 0
                        p = _stats[idx]
                    else:
                        p = 0
                elif event.num == 3:
                    p = 10
                elif event.num == 4:
                    if p <= 0:
                        p = 0.06
                    elif p < 5:
                        p *=1.2
                    else:
                       p +=5 #1.1
                elif event.num == 5:
                    if p <= 5:
                        p *=0.8
                    else:
                        p -= 5 #1.1
                #p =int(p)
                
                if p > 4000:
                    p = 4000
                if p < 0.05:
                    p =0
                if p > 5 and p < 10: #bug
                    p =5

                if p < 0:
                    ct.elem[self.attr]["text"] = "SPEED:\noff".format(p)
                else:
                    ct.elem[self.attr]["text"] = "SPEED:\n{:0.02f}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("START:"):#SIN":
                #global prm
                k = "START"
                p = prm[k]
                if event.num == 1:
                    pass
                elif event.num == 2:
                    pass
                elif event.num == 4:
                    if p <= 0:
                        p = 1
                    p += 5 #1.1
                elif event.num == 5:
                    p -= 5 #1.1
                #p =int(p)
                
                if p > 4000:
                    p = 4000
                if p < 5:
                    p =0
                if p == 6: #bug
                    p =5

                ct.elem[self.attr]["text"] = "START:\n{:0.0f}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("WIDTH:"):#SIN":
                #global prm
                k = "WIDTH"
                p = prm[k]
                if event.num == 1:
                    _stats = [0,25,50,75,10]
                    if p in _stats:
                        idx = _stats.index(p)+1
                        if idx > len(_stats)-1: #rotate
                            idx = 0
                        p = _stats[idx]
                    else:
                        p = 25
                elif event.num == 2:
                    p = 50
                elif event.num == 3:
                    p = 100
                elif event.num == 4:
                    if p <= 0:
                        p = 1
                    elif p == 50:
                        p = 100
                    elif p == 5:
                        p = 25
                    elif p == 25:
                        p = 50
                    else:
                        p += 5 #*=1.1
                elif event.num == 5:
                    if p == 10:
                        p = 5
                    elif p == 25:
                        p = 10
                    elif p == 50:
                        p = 25
                    elif p == 100:
                        p = 50
                    #else:
                    #    p -=5 #/=1.1
                    
                #p =int(p)
                
                if p < 0:
                    p = 0
                if p > 100:
                    p = 100
                if p == 6: #bug
                    p =5
                if p > 25 and p < 50: #bug
                    p =50
                if p > 50 and p < 75: #bug
                    p =75
                if p > 75 and p < 100: #bug
                    p =100

                ct.elem[self.attr]["text"] = "WIDTH:\n{:0.0f}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("DIR:"):#SIN":
                #global prm
                k = "DIR"
                p = prm[k]
                if event.num == 1:
                    p = 1
                elif event.num == 3:
                    p = -1
                elif event.num == 4:
                    p = 1
                elif event.num == 5:
                    p =-1
                txt = p 
                ct.elem[self.attr]["text"] = "DIR:\n{}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("SHUFFLE:"):#SIN":
                #global prm
                k = "SHUFFLE"
                print("OOO", [self.mode,k , prm] )
                p = prm[k]
                if event.num == 1:
                    p = 0
                elif event.num == 3:
                    p = 1
                elif event.num == 4:
                    p = 1
                elif event.num == 5:
                    p =0
                if p == 6: #bug ?
                    p =5
                ct.elem[self.attr]["text"] = k+":\n{}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("INVERT:"):#SIN":
                #global prm
                k = "INVERT"
                p = prm[k]
                if event.num == 1:
                    p = 0
                elif event.num == 3:
                    p = 1
                elif event.num == 4:
                    p = 1
                elif event.num == 5:
                    p =0
                if p == 6: #bug ?
                    p =5
                ct.elem[self.attr]["text"] = k+":\n{}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("2D-X:"):#SIN":
                #global prm
                k = "2D-X"
                p = prm[k]
                if event.num == 1:
                    p = 1
                elif event.num == 3:
                    p = 2
                elif event.num == 4:
                    p += 1
                elif event.num == 5:
                    p -=1
                if p > 100:
                    p = 100
                if p < 1:
                    p =1
                    
                txt = p 
                ct.elem[self.attr]["text"] = "2D-X:\n{}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("WING:"):#SIN":
                #global prm
                k = "WING"
                p = prm[k]
                if event.num == 1:
                    p = 1
                elif event.num == 3:
                    p = 2
                elif event.num == 4:
                    p += 1
                elif event.num == 5:
                    p -=1
                if p > 100:
                    p = 100
                if p < 1:
                    p =1
                    
                txt = p 
                ct.elem[self.attr]["text"] = "WING:\n{}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("OFFSET:"):#SIN":
                #global prm
                k = "OFFSET"
                p = prm[k]
                if event.num == 1:
                    p = 50
                elif event.num == 2:
                    p *= 2
                elif event.num == 3:
                    p = 100
                elif event.num == 4:
                    if p <= 0:
                        p = 1
                    p +=5 #*=1.1
                elif event.num == 5:
                    p -=5 #/=1.1
                #p =int(p)
                
                #if p > 512:
                #    p = 512
                if p < 5:
                    p =0
                if p == 6: #bug
                    p =5

                ct.elem[self.attr]["text"] = "OFFSET:\n{:0.0f}".format(p)
                cprint("  ",prm)
                prm[k] = p
            elif self.attr.startswith("BASE:"):
                k = "BASE"
                p = prm[k]
                if event.num == 1:
                    p = "-"
                elif event.num == 3:
                    p = "0"
                elif event.num == 4:
                    p = "+"
                elif event.num == 5:
                    p = "0"
                ct.elem[self.attr]["text"] = "BASE:\n{}".format(p)
                prm[k] = p
            elif self.attr.startswith("2D:"):#SIN":
                self.fx(event)
            elif self.attr.startswith("FX:"):#SIN":
                self.fx(event)

            elif self.attr == "FX OFF":
                if event.num == 1:
                    MAIN.FIXTURES.fx_off("all")
                    MAIN.CONSOLE.fx_off("all")
                    MAIN.CONSOLE.flash_off("all")
                    MAIN.master._refresh_fix()
                    return 0

                #if event.num == 1:
            elif self.attr == "REC-FX":
                cprint("  ",self.attr)
                MAIN.modes.val(self.attr,1)
                #MAIN.modes.val(self.attr,1)
                #MAIN.modes.val("REC",1)

            return 0
            
    def cb(self,event):
        cprint("tkevent.EVENT_fx.cb:",self.attr,self.mode,event,color='yellow')
        cprint(["type",event.type,"num",event.num])
        try:
            change = 0

            if self.mode.startswith("FX"):
                self.command(event)
                return 0

        except Exception as e:
            cprint("== cb EXCEPT",e,color="red")
            cprint("Error on line {}".format(sys.exc_info()[-1].tb_lineno),color="red")
            cprint(''.join(traceback.format_exception(None, e, e.__traceback__)),color="red")
        return 1